Skip to content

Commit 6e19022

Browse files
committed
fix(sandbox): preserve standard sbin paths for CDI workloads
Signed-off-by: Evan Lezar <elezar@nvidia.com>
1 parent 1178d92 commit 6e19022

5 files changed

Lines changed: 626 additions & 18 deletions

File tree

‎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,
@@ -120,6 +122,13 @@ impl LocalBoundaryExec {
120122
})
121123
}
122124

125+
/// Configure whether workload paths should include the standard sbin directories.
126+
#[must_use]
127+
pub fn with_standard_sbin_path_repair(mut self, enabled: bool) -> Self {
128+
self.repair_standard_sbin = enabled;
129+
self
130+
}
131+
123132
fn command(&self, spec: &ExecSpec) -> Result<Command, BackendError> {
124133
let (program, args) = if let Some(shell_spec) = &spec.shell {
125134
let shell = openshell_core::shell::find_login_shell().ok_or_else(|| {
@@ -150,12 +159,18 @@ impl LocalBoundaryExec {
150159
if program.is_empty() {
151160
return Err(BackendError::Process("exec program is empty".to_string()));
152161
}
162+
let repair_standard_sbin = self.repair_standard_sbin;
163+
let args = crate::process::process_args_with_standard_sbin_paths(
164+
&program,
165+
&args,
166+
repair_standard_sbin,
167+
);
153168
let mut command = Command::new(&program);
154-
command.args(&args);
169+
command.args(args);
155170
let effective_workdir = spec.workdir.as_deref().or(self.base_workdir.as_deref());
156171
let (session_user, session_home) =
157172
crate::process::session_user_and_home(&self.policy, effective_workdir);
158-
let path = std::env::var("PATH").unwrap_or_else(|_| "/usr/local/bin:/usr/bin:/bin".into());
173+
let path = crate::child_env::child_path_from_env(repair_standard_sbin);
159174
command
160175
.env_clear()
161176
.env(openshell_core::sandbox_env::SANDBOX, "1")
@@ -168,7 +183,17 @@ impl LocalBoundaryExec {
168183
}
169184
for (key, value) in &self.user_environment {
170185
if !key.starts_with("OPENSHELL_") {
171-
command.env(key, value);
186+
if key == "PATH" {
187+
command.env(
188+
key,
189+
crate::child_env::maybe_path_with_standard_sbin_paths(
190+
value,
191+
repair_standard_sbin,
192+
),
193+
);
194+
} else {
195+
command.env(key, value);
196+
}
172197
}
173198
}
174199
if let Some((ca_cert_path, combined_bundle_path)) = self.ca_file_paths.as_deref() {
@@ -178,13 +203,33 @@ impl LocalBoundaryExec {
178203
}
179204
for (key, value) in self.provider_credentials.child_env_with_gcp_resolved() {
180205
if !crate::process::is_supervisor_only_env_var(&key) {
181-
command.env(key, value);
206+
if key == "PATH" {
207+
command.env(
208+
key,
209+
crate::child_env::maybe_path_with_standard_sbin_paths(
210+
&value,
211+
repair_standard_sbin,
212+
),
213+
);
214+
} else {
215+
command.env(key, value);
216+
}
182217
}
183218
}
184219
crate::process::strip_proxy_env_std(&mut command);
185220
for (key, value) in &spec.env {
186221
if !key.starts_with("OPENSHELL_") {
187-
command.env(key, value);
222+
if key == "PATH" {
223+
command.env(
224+
key,
225+
crate::child_env::maybe_path_with_standard_sbin_paths(
226+
value,
227+
repair_standard_sbin,
228+
),
229+
);
230+
} else {
231+
command.env(key, value);
232+
}
188233
}
189234
}
190235
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
@@ -2587,6 +2587,7 @@ mod linux {
25872587
process_id: format!("{}:main:0", self.config.generation),
25882588
spec,
25892589
policy,
2590+
cdi_active: self.config.cdi_context.is_some(),
25902591
provider_env_revision,
25912592
provider_env,
25922593
ca_file_paths,
@@ -2933,6 +2934,7 @@ mod linux {
29332934
process_id: String,
29342935
spec: AgentSpecWire,
29352936
policy: openshell_core::policy::SandboxPolicy,
2937+
cdi_active: bool,
29362938
provider_env_revision: u64,
29372939
provider_env: std::collections::HashMap<String, String>,
29382940
ca_file_paths: Option<(std::path::PathBuf, std::path::PathBuf)>,
@@ -2967,6 +2969,7 @@ mod linux {
29672969
process_id,
29682970
spec,
29692971
policy,
2972+
cdi_active,
29702973
provider_env_revision,
29712974
provider_env,
29722975
ca_file_paths,
@@ -2987,6 +2990,7 @@ mod linux {
29872990
spec.timeout_secs,
29882991
spec.interactive,
29892992
&policy,
2993+
cdi_active,
29902994
entrypoint_pid,
29912995
provider_credentials.clone(),
29922996
provider_env,
@@ -5240,6 +5244,7 @@ containerEdits:
52405244
process_id: "generation-retained:main:0".to_string(),
52415245
spec: agent_spec.clone(),
52425246
policy,
5247+
cdi_active: false,
52435248
provider_env_revision: 0,
52445249
provider_env: std::collections::HashMap::new(),
52455250
ca_file_paths: None,

0 commit comments

Comments
 (0)