From bfab8c129c5e490fab2a6fa5f67249db352c2896 Mon Sep 17 00:00:00 2001 From: David Lattimore Date: Thu, 21 Sep 2023 17:12:24 +1000 Subject: [PATCH] refactoring: Pass whole command into sandbox rather than just a binary path --- src/proxy/subprocess.rs | 5 +++-- src/sandbox.rs | 7 ++++--- src/sandbox/bubblewrap.rs | 30 ++++++++++++++++++++---------- 3 files changed, 27 insertions(+), 15 deletions(-) diff --git a/src/proxy/subprocess.rs b/src/proxy/subprocess.rs index 74fa6bf..b76a46a 100644 --- a/src/proxy/subprocess.rs +++ b/src/proxy/subprocess.rs @@ -146,7 +146,8 @@ fn proxy_binary( return Ok(Command::new(&orig_bin).status()?.into()); }; - let output = sandbox.run(&orig_bin)?; + let command = Command::new(&orig_bin); + let output = sandbox.run(&command)?; let rpc_response = rpc_client.build_script_complete({ let exit_code = output.status.code().unwrap_or(-1); BinExecutionOutput { @@ -157,7 +158,7 @@ fn proxy_binary( sandbox_config, build_script: orig_bin.clone(), sandbox_config_display: (exit_code != 0) - .then(|| sandbox.display_to_run(&orig_bin).to_string()), + .then(|| sandbox.display_to_run(&command).to_string()), } })?; match rpc_response { diff --git a/src/sandbox.rs b/src/sandbox.rs index 81b1426..1f8ff39 100644 --- a/src/sandbox.rs +++ b/src/sandbox.rs @@ -8,12 +8,13 @@ use std::ffi::OsStr; use std::fmt::Display; use std::path::Path; use std::path::PathBuf; +use std::process::Command; mod bubblewrap; pub(crate) trait Sandbox { - /// Runs `binary` inside the sandbox. - fn run(&self, binary: &Path) -> Result; + /// Runs `command` inside the sandbox. + fn run(&self, command: &Command) -> Result; /// Bind a tmpfs at `dir`. fn tmpfs(&mut self, dir: &Path); @@ -52,7 +53,7 @@ pub(crate) trait Sandbox { /// Returns an object that when displayed serves to tell the user what the sandbox would do. /// e.g. the command that would be run with all flags. - fn display_to_run(&self, binary: &Path) -> Box; + fn display_to_run(&self, command: &Command) -> Box; } pub(crate) fn from_config( diff --git a/src/sandbox/bubblewrap.rs b/src/sandbox/bubblewrap.rs index 01f6a0f..cd2d53a 100644 --- a/src/sandbox/bubblewrap.rs +++ b/src/sandbox/bubblewrap.rs @@ -17,9 +17,9 @@ impl Bubblewrap { self.args.push(arg.as_ref().to_owned()); } - fn command(&self, binary: &Path) -> Command { - let mut command = Command::new("bwrap"); - command + fn command(&self, command: &Command) -> Command { + let mut bwrap_command = Command::new("bwrap"); + bwrap_command .args(["--unshare-all"]) .args(["--uid", "1000"]) .args(["--gid", "1000"]) @@ -28,9 +28,19 @@ impl Bubblewrap { .args(["--clearenv"]) .args(&self.args) .args(["--dev", "/dev"]) - .args(["--proc", "/proc"]) - .arg(binary); - command + .args(["--proc", "/proc"]); + for (var_name, value) in command.get_envs() { + if let Some(value) = value { + bwrap_command.arg("--setenv").arg(var_name).arg(value); + } else { + bwrap_command.arg("--unsetenv").arg(var_name); + } + } + bwrap_command + .arg("--") + .arg(command.get_program()) + .args(command.get_args()); + bwrap_command } } @@ -69,8 +79,8 @@ impl Sandbox for Bubblewrap { self.arg("--share-net"); } - fn run(&self, binary: &Path) -> Result { - let mut command = self.command(binary); + fn run(&self, command: &Command) -> Result { + let mut command = self.command(command); command.output().with_context(|| { format!( "Failed to run sandbox command: {}", @@ -79,9 +89,9 @@ impl Sandbox for Bubblewrap { }) } - fn display_to_run(&self, binary: &Path) -> Box { + fn display_to_run(&self, command: &Command) -> Box { Box::new(CommandDisplay { - command: self.command(binary), + command: self.command(command), }) } }