From c7ce2309c29c45a79621f278fd1b65c814f99da9 Mon Sep 17 00:00:00 2001 From: Adam Bratschi-Kaye Date: Mon, 9 Dec 2024 22:38:08 +0100 Subject: [PATCH] fix(EXC-1811): Disable `anyhow` backtraces in sandbox (#2991) EXC-1811 As of version 1.0.77, the `anyhow` crate will capture a backtrace any time an error is generated (if `RUST_BACKTRACE` is set). This triggers some SELinux denials in the sandbox because libunwind reads and writes to a pipe when capturing the backtrace. We can disable the capturing in the sandbox by setting the `RUST_LIB_BACKTRACE` env variable since we don't use these backtraces anyway. --- rs/canister_sandbox/src/launcher.rs | 9 +++++++-- rs/canister_sandbox/src/process.rs | 9 ++++++++- .../src/replica_controller/launch_as_process.rs | 2 +- 3 files changed, 16 insertions(+), 4 deletions(-) diff --git a/rs/canister_sandbox/src/launcher.rs b/rs/canister_sandbox/src/launcher.rs index 7f021e16752..ce08eb6f7f8 100644 --- a/rs/canister_sandbox/src/launcher.rs +++ b/rs/canister_sandbox/src/launcher.rs @@ -174,7 +174,12 @@ impl LauncherService for LauncherServer { socket, }: LaunchSandboxRequest, ) -> rpc::Call { - match spawn_socketed_process(&sandbox_exec_path, &argv, socket) { + match spawn_socketed_process( + &sandbox_exec_path, + &argv, + &[("RUST_LIB_BACKTRACE", "0")], + socket, + ) { Ok(child_handle) => { // Ensure the launcher closes its end of the socket. drop(unsafe { UnixStream::from_raw_fd(socket) }); @@ -218,7 +223,7 @@ impl LauncherService for LauncherServer { args.push("--embedder-config".to_string()); args.push(self.embedder_config_arg.clone()); - match spawn_socketed_process(&exec_path, &args, socket) { + match spawn_socketed_process(&exec_path, &args, &[], socket) { Ok(child_handle) => { // Ensure the launcher closes its end of the socket. drop(unsafe { UnixStream::from_raw_fd(socket) }); diff --git a/rs/canister_sandbox/src/process.rs b/rs/canister_sandbox/src/process.rs index 6c7c1e465ba..3b9d1c33c75 100644 --- a/rs/canister_sandbox/src/process.rs +++ b/rs/canister_sandbox/src/process.rs @@ -18,10 +18,14 @@ use std::sync::Arc; pub fn spawn_socketed_process( exec_path: &str, argv: &[String], + env: &[(&str, &str)], socket: RawFd, ) -> std::io::Result { let mut cmd = Command::new(exec_path); cmd.args(argv); + for (k, v) in env { + cmd.env(k, v); + } // In case of Command we inherit the current process's environment. This should // particularly include things such as Rust backtrace flags. It might be @@ -46,6 +50,7 @@ pub fn spawn_socketed_process( Ok(child_handle) } +/// Only used for testing setups. /// Spawn a canister sandbox process and yield RPC interface object to /// communicate with it. /// @@ -61,6 +66,8 @@ pub fn spawn_canister_sandbox_process( ) -> std::io::Result<(Arc, Pid, std::thread::JoinHandle<()>)> { spawn_canister_sandbox_process_with_factory(exec_path, argv, controller_service, safe_shutdown) } + +/// Only used for testing setups. /// Spawn a canister sandbox process and yield RPC interface object to /// communicate with it. When the socket is closed by the other side, /// we check if the safe_shutdown flag was set. If not this function @@ -77,7 +84,7 @@ pub fn spawn_canister_sandbox_process_with_factory( safe_shutdown: Arc, ) -> std::io::Result<(Arc, Pid, std::thread::JoinHandle<()>)> { let (socket, sock_sandbox) = std::os::unix::net::UnixStream::pair()?; - let pid = spawn_socketed_process(exec_path, argv, sock_sandbox.as_raw_fd())?.id() as i32; + let pid = spawn_socketed_process(exec_path, argv, &[], sock_sandbox.as_raw_fd())?.id() as i32; let socket = Arc::new(socket); diff --git a/rs/canister_sandbox/src/replica_controller/launch_as_process.rs b/rs/canister_sandbox/src/replica_controller/launch_as_process.rs index 1e21bf36489..95b748769c3 100644 --- a/rs/canister_sandbox/src/replica_controller/launch_as_process.rs +++ b/rs/canister_sandbox/src/replica_controller/launch_as_process.rs @@ -26,7 +26,7 @@ pub fn spawn_launcher_process( >, ) -> std::io::Result<(Box, Child)> { let (socket, sock_launcher) = std::os::unix::net::UnixStream::pair()?; - let child_handle = spawn_socketed_process(exec_path, argv, sock_launcher.as_raw_fd())?; + let child_handle = spawn_socketed_process(exec_path, argv, &[], sock_launcher.as_raw_fd())?; let socket = Arc::new(socket);