sirenia: Add Sandbox trait
This change converts Sandbox to a trait from an impl. This trait will be
implemented by different type of apps running in sandboxes in ManaTEE.
BUG=b:196186396
TEST=Unit tests.
Change-Id: I97db4828afcf50f061bd91977635c577a949bcb9
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform2/+/3163768
Reviewed-by: Abhishek Bhardwaj <abhishekbh@chromium.org>
Reviewed-by: Allen Webb <allenwebb@google.com>
Tested-by: Abhishek Bhardwaj <abhishekbh@chromium.org>
Auto-Submit: Abhishek Bhardwaj <abhishekbh@chromium.org>
Commit-Queue: Abhishek Bhardwaj <abhishekbh@chromium.org>
diff --git a/sirenia/libsirenia/src/sandbox/mod.rs b/sirenia/libsirenia/src/sandbox/mod.rs
index 289b9a9..7de61ea 100644
--- a/sirenia/libsirenia/src/sandbox/mod.rs
+++ b/sirenia/libsirenia/src/sandbox/mod.rs
@@ -33,10 +33,22 @@
const NEW_ROOT: &str = "/mnt/empty";
-/// An abstraction for the TEE application sandbox.
-pub struct Sandbox(minijail::Minijail);
+pub trait Sandbox {
+ /// Execute `cmd` with the specified arguments `args`. The specified file
+ /// descriptors are connected to stdio for the child process.
+ fn run(&mut self, cmd: &Path, args: &[&str], keep_fds: &[(RawFd, RawFd)]) -> Result<pid_t>;
-impl Sandbox {
+ fn run_raw(&mut self, cmd: RawFd, args: &[&str], keep_fds: &[(RawFd, RawFd)]) -> Result<pid_t>;
+
+ /// Wait until the child process completes. Non-zero return codes are
+ /// returned as an error.
+ fn wait_for_completion(&mut self) -> Result<()>;
+}
+
+/// An abstraction for the TEE application sandbox.
+pub struct MinijailSandbox(minijail::Minijail);
+
+impl MinijailSandbox {
/// Setup default sandbox / namespaces
pub fn new(seccomp_bpf_file: Option<&Path>) -> Result<Self> {
// All child jails run in a new user namespace without any users mapped,
@@ -73,19 +85,19 @@
j.set_rlimit(libc::RLIMIT_NOFILE as i32, limit, limit)
.map_err(Error::SettingMaxOpenFiles)?;
- Ok(Sandbox(j))
+ Ok(MinijailSandbox(j))
}
/// A version of the sandbox for use with tests because it doesn't require
/// elevated privilege. It is also used for developer tools.
pub fn passthrough() -> Result<Self> {
let j = Minijail::new().map_err(Error::Jail)?;
- Ok(Sandbox(j))
+ Ok(MinijailSandbox(j))
}
+}
- /// Execute `cmd` with the specified arguments `args`. The specified file
- /// descriptors are connected to stdio for the child process.
- pub fn run(&mut self, cmd: &Path, args: &[&str], keep_fds: &[(RawFd, RawFd)]) -> Result<pid_t> {
+impl Sandbox for MinijailSandbox {
+ fn run(&mut self, cmd: &Path, args: &[&str], keep_fds: &[(RawFd, RawFd)]) -> Result<pid_t> {
let pid = match self
.0
.run_remap(cmd, keep_fds, args)
@@ -100,12 +112,7 @@
Ok(pid)
}
- pub fn run_raw(
- &mut self,
- cmd: RawFd,
- args: &[&str],
- keep_fds: &[(RawFd, RawFd)],
- ) -> Result<pid_t> {
+ fn run_raw(&mut self, cmd: RawFd, args: &[&str], keep_fds: &[(RawFd, RawFd)]) -> Result<pid_t> {
let pid = match self
.0
.run_fd_remap(&cmd, keep_fds, args)
@@ -120,9 +127,7 @@
Ok(pid)
}
- /// Wait until the child process completes. Non-zero return codes are
- /// returned as an error.
- pub fn wait_for_completion(&mut self) -> Result<()> {
+ fn wait_for_completion(&mut self) -> Result<()> {
self.0.wait().map_err(Error::Wait)
}
}
@@ -138,7 +143,7 @@
use crate::transport::{CROS_CONNECTION_ERR_FD, CROS_CONNECTION_R_FD, CROS_CONNECTION_W_FD};
- fn do_test(mut s: Sandbox) {
+ fn do_test(s: &mut dyn Sandbox) {
const STDOUT_TEST: &str = "stdout test";
const STDERR_TEST: &str = "stderr test";
@@ -197,13 +202,13 @@
#[test]
#[ignore] // privileged operation.
fn sandbox() {
- let s = Sandbox::new(None).unwrap();
- do_test(s);
+ let mut s = MinijailSandbox::new(None).unwrap();
+ do_test(&mut s);
}
#[test]
fn sandbox_unpriviledged() {
- let s = Sandbox::passthrough().unwrap();
- do_test(s);
+ let mut s = MinijailSandbox::passthrough().unwrap();
+ do_test(&mut s);
}
}
diff --git a/sirenia/src/trichechus.rs b/sirenia/src/trichechus.rs
index a255719..1c60a7c 100644
--- a/sirenia/src/trichechus.rs
+++ b/sirenia/src/trichechus.rs
@@ -33,7 +33,7 @@
syslog::{Syslog, SyslogReceiverMut, SYSLOG_PATH},
},
rpc::{self, ConnectionHandler, RpcDispatcher, TransportServer},
- sandbox::{self, Sandbox},
+ sandbox::{self, MinijailSandbox, Sandbox},
to_sys_util,
transport::{
self, create_transport_from_pipes, Transport, TransportType, CROS_CID,
@@ -92,7 +92,7 @@
/* Holds the trichechus-relevant information for a TEEApp. */
struct TeeApp {
- sandbox: Sandbox,
+ sandbox: Box<dyn Sandbox>,
app_info: AppManifestEntry,
}
@@ -431,14 +431,20 @@
) -> StdResult<(), trichechus::Error> {
let app_info = lookup_app_info(state, app_id)?.to_owned();
- let sandbox = match &app_info.sandbox_type {
- SandboxType::DeveloperEnvironment => Sandbox::passthrough(),
- SandboxType::Container => Sandbox::new(None),
- SandboxType::VirtualMachine => {
- return Err(trichechus::Error::SandboxTypeNotImplemented);
- }
- }
- .map_err(|err| trichechus::Error::from(format!("Failed create sandbox: {:?}", err)))?;
+ let sandbox =
+ match &app_info.sandbox_type {
+ SandboxType::DeveloperEnvironment => {
+ Box::new(MinijailSandbox::passthrough().map_err(|err| {
+ trichechus::Error::from(format!("Failed create sandbox: {:?}", err))
+ })?)
+ }
+ SandboxType::Container => Box::new(MinijailSandbox::new(None).map_err(|err| {
+ trichechus::Error::from(format!("Failed create sandbox: {:?}", err))
+ })?),
+ SandboxType::VirtualMachine => {
+ return Err(trichechus::Error::SandboxTypeNotImplemented);
+ }
+ };
// Do some additional checks to fail early and return the reason to the caller.
match &app_info.exec_info {