Skip to content

Commit 5cb218d

Browse files
committed
fix(sandbox): preserve standard sbin paths for CDI workloads
Signed-off-by: Evan Lezar <elezar@nvidia.com>
1 parent 7fcd175 commit 5cb218d

6 files changed

Lines changed: 626 additions & 19 deletions

File tree

‎crates/openshell-core/testdata/orin-nvidia.yaml‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2216,4 +2216,3 @@ containerEdits:
22162216
- nodev
22172217
- rbind
22182218
- rprivate
2219-

‎crates/openshell-sandbox/src/boundary_exec.rs‎

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ pub struct LocalBoundaryExec {
3535
ca_file_paths: Option<Arc<(std::path::PathBuf, std::path::PathBuf)>>,
3636
provider_credentials: ProviderCredentialState,
3737
user_environment: HashMap<String, String>,
38+
repair_standard_sbin: bool,
3839
runtime: Arc<crate::boundary_io::BoundaryRuntimeState>,
3940
#[cfg(target_os = "linux")]
4041
launcher: openshell_isolation_interface::linux::workload_launcher::WorkloadLauncher,
@@ -59,6 +60,7 @@ impl LocalBoundaryExec {
5960
ca_file_paths,
6061
provider_credentials,
6162
user_environment,
63+
repair_standard_sbin: false,
6264
runtime,
6365
#[cfg(target_os = "linux")]
6466
launcher,
@@ -121,6 +123,13 @@ impl LocalBoundaryExec {
121123
})
122124
}
123125

126+
/// Configure whether workload paths should include the standard sbin directories.
127+
#[must_use]
128+
pub fn with_standard_sbin_path_repair(mut self, enabled: bool) -> Self {
129+
self.repair_standard_sbin = enabled;
130+
self
131+
}
132+
124133
fn command(&self, spec: &ExecSpec) -> Result<Command, BackendError> {
125134
let (program, args) = if let Some(shell_spec) = &spec.shell {
126135
let shell = openshell_core::shell::find_login_shell().ok_or_else(|| {
@@ -151,12 +160,18 @@ impl LocalBoundaryExec {
151160
if program.is_empty() {
152161
return Err(BackendError::Process("exec program is empty".to_string()));
153162
}
163+
let repair_standard_sbin = self.repair_standard_sbin;
164+
let args = crate::process::process_args_with_standard_sbin_paths(
165+
&program,
166+
&args,
167+
repair_standard_sbin,
168+
);
154169
let mut command = Command::new(&program);
155-
command.args(&args);
170+
command.args(args);
156171
let effective_workdir = spec.workdir.as_deref().or(self.base_workdir.as_deref());
157172
let (session_user, session_home) =
158173
crate::process::session_user_and_home(&self.policy, effective_workdir);
159-
let path = std::env::var("PATH").unwrap_or_else(|_| "/usr/local/bin:/usr/bin:/bin".into());
174+
let path = crate::child_env::child_path_from_env(repair_standard_sbin);
160175
command
161176
.env_clear()
162177
.env(openshell_core::sandbox_env::SANDBOX, "1")
@@ -169,7 +184,17 @@ impl LocalBoundaryExec {
169184
}
170185
for (key, value) in &self.user_environment {
171186
if !key.starts_with("OPENSHELL_") {
172-
command.env(key, value);
187+
if key == "PATH" {
188+
command.env(
189+
key,
190+
crate::child_env::maybe_path_with_standard_sbin_paths(
191+
value,
192+
repair_standard_sbin,
193+
),
194+
);
195+
} else {
196+
command.env(key, value);
197+
}
173198
}
174199
}
175200
if let Some((ca_cert_path, combined_bundle_path)) = self.ca_file_paths.as_deref() {
@@ -179,13 +204,33 @@ impl LocalBoundaryExec {
179204
}
180205
for (key, value) in self.provider_credentials.child_env_with_gcp_resolved() {
181206
if !crate::process::is_supervisor_only_env_var(&key) {
182-
command.env(key, value);
207+
if key == "PATH" {
208+
command.env(
209+
key,
210+
crate::child_env::maybe_path_with_standard_sbin_paths(
211+
&value,
212+
repair_standard_sbin,
213+
),
214+
);
215+
} else {
216+
command.env(key, value);
217+
}
183218
}
184219
}
185220
crate::process::strip_proxy_env_std(&mut command);
186221
for (key, value) in &spec.env {
187222
if !key.starts_with("OPENSHELL_") {
188-
command.env(key, value);
223+
if key == "PATH" {
224+
command.env(
225+
key,
226+
crate::child_env::maybe_path_with_standard_sbin_paths(
227+
value,
228+
repair_standard_sbin,
229+
),
230+
);
231+
} else {
232+
command.env(key, value);
233+
}
189234
}
190235
}
191236
if let Some(workdir) = spec.workdir.as_deref().or(self.base_workdir.as_deref()) {

‎crates/openshell-sandbox/src/boundary_server.rs‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2615,6 +2615,7 @@ mod linux {
26152615
process_id: format!("{}:main:0", self.config.generation),
26162616
spec,
26172617
policy,
2618+
cdi_active: self.config.cdi_context.is_some(),
26182619
provider_env_revision,
26192620
provider_env,
26202621
ca_file_paths,
@@ -2961,6 +2962,7 @@ mod linux {
29612962
process_id: String,
29622963
spec: AgentSpecWire,
29632964
policy: openshell_core::policy::SandboxPolicy,
2965+
cdi_active: bool,
29642966
provider_env_revision: u64,
29652967
provider_env: std::collections::HashMap<String, String>,
29662968
ca_file_paths: Option<(std::path::PathBuf, std::path::PathBuf)>,
@@ -2995,6 +2997,7 @@ mod linux {
29952997
process_id,
29962998
spec,
29972999
policy,
3000+
cdi_active,
29983001
provider_env_revision,
29993002
provider_env,
30003003
ca_file_paths,
@@ -3015,6 +3018,7 @@ mod linux {
30153018
spec.timeout_secs,
30163019
spec.interactive,
30173020
&policy,
3021+
cdi_active,
30183022
entrypoint_pid,
30193023
provider_credentials.clone(),
30203024
provider_env,
@@ -5327,6 +5331,7 @@ containerEdits:
53275331
process_id: "generation-retained:main:0".to_string(),
53285332
spec: agent_spec.clone(),
53295333
policy,
5334+
cdi_active: false,
53305335
provider_env_revision: 0,
53315336
provider_env: std::collections::HashMap::new(),
53325337
ca_file_paths: None,

0 commit comments

Comments
 (0)