Skip to content

Commit 371a2ea

Browse files
committed
fix(sandbox): preserve standard sbin paths for CDI workloads
Signed-off-by: Evan Lezar <elezar@nvidia.com>
1 parent 966d8ea commit 371a2ea

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
@@ -2732,6 +2732,7 @@ mod linux {
27322732
process_id: format!("{}:main:0", self.config.generation),
27332733
spec,
27342734
policy,
2735+
cdi_active: self.config.cdi_context.is_some(),
27352736
provider_env_revision,
27362737
provider_env,
27372738
ca_file_paths,
@@ -3124,6 +3125,7 @@ mod linux {
31243125
process_id: String,
31253126
spec: AgentSpecWire,
31263127
policy: openshell_core::policy::SandboxPolicy,
3128+
cdi_active: bool,
31273129
provider_env_revision: u64,
31283130
provider_env: std::collections::HashMap<String, String>,
31293131
ca_file_paths: Option<(std::path::PathBuf, std::path::PathBuf)>,
@@ -3158,6 +3160,7 @@ mod linux {
31583160
process_id,
31593161
spec,
31603162
policy,
3163+
cdi_active,
31613164
provider_env_revision,
31623165
provider_env,
31633166
ca_file_paths,
@@ -3178,6 +3181,7 @@ mod linux {
31783181
spec.timeout_secs,
31793182
spec.interactive,
31803183
&policy,
3184+
cdi_active,
31813185
entrypoint_pid,
31823186
provider_credentials.clone(),
31833187
provider_env,
@@ -5734,6 +5738,7 @@ containerEdits:
57345738
process_id: "generation-retained:main:0".to_string(),
57355739
spec: agent_spec.clone(),
57365740
policy,
5741+
cdi_active: false,
57375742
provider_env_revision: 0,
57385743
provider_env: std::collections::HashMap::new(),
57395744
ca_file_paths: None,

0 commit comments

Comments
 (0)