From c07d6df1635045eaad9a2c915c78634789b5a2ff Mon Sep 17 00:00:00 2001 From: Jake Hillion Date: Tue, 17 May 2022 13:24:13 +0100 Subject: [PATCH 1/2] mount proc --- src/spawner/mod.rs | 8 ++++++++ src/specification.rs | 2 ++ src/void.rs | 29 +++++++++++++++++++++++++++-- 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/src/spawner/mod.rs b/src/spawner/mod.rs index 06880c5..d460c41 100644 --- a/src/spawner/mod.rs +++ b/src/spawner/mod.rs @@ -105,6 +105,8 @@ impl<'a> Spawner<'a> { let pipe = self.pipes.get_mut(s).unwrap().take_read()?; builder.keep_fd(&pipe); + builder.mount("/proc", "/proc").remount_proc(); + let closure = || match self.pipe_trigger(pipe, entrypoint, name) { Ok(()) => exitcode::OK, Err(e) => { @@ -129,6 +131,8 @@ impl<'a> Spawner<'a> { let socket = self.sockets.get_mut(s).unwrap().take_read()?; builder.keep_fd(&socket); + builder.mount("/proc", "/proc").remount_proc(); + let closure = || match self.file_socket_trigger(socket, entrypoint, name) { Ok(()) => exitcode::OK, Err(e) => { @@ -327,6 +331,10 @@ impl<'a> Spawner<'a> { Environment::DomainName(name) => { builder.set_domain_name(name); } + + Environment::Procfs => { + builder.mount("/proc", "/proc").remount_proc(); + } } } } diff --git a/src/specification.rs b/src/specification.rs index 2ce9c97..18d9de7 100644 --- a/src/specification.rs +++ b/src/specification.rs @@ -117,6 +117,8 @@ pub enum Environment { Hostname(String), DomainName(String), + + Procfs, } #[derive(Serialize, Deserialize, PartialEq, Eq, Hash, Debug)] diff --git a/src/void.rs b/src/void.rs index 06a4eda..1b02e92 100644 --- a/src/void.rs +++ b/src/void.rs @@ -33,6 +33,8 @@ pub struct VoidBuilder { mounts: HashMap, fds: HashSet, + + remount_proc: bool, } impl VoidBuilder { @@ -42,6 +44,7 @@ impl VoidBuilder { domain_name: None, mounts: HashMap::new(), fds: HashSet::new(), + remount_proc: false, } } @@ -65,6 +68,11 @@ impl VoidBuilder { self } + pub fn remount_proc(&mut self) -> &mut Self { + self.remount_proc = true; + self + } + pub fn spawn(&mut self, child_fn: impl FnOnce() -> i32) -> Result { let mut args = CloneArgs::new( CloneFlags::CLONE_NEWCGROUP @@ -252,12 +260,29 @@ impl VoidBuilder { fs::write(&dst, b"")?; } - // bind mount + // rbind mount mount( Some(&src), &dst, Option::<&str>::None, - MsFlags::MS_BIND, + MsFlags::MS_BIND | MsFlags::MS_REC, + Option::<&str>::None, + ) + .map_err(|e| Error::Nix { + msg: "mount", + src: e, + })?; + } + + // remount proc + if self.remount_proc { + debug!("remounting /proc`"); + + mount( + Some("proc"), + "/proc", + Some("proc"), + MsFlags::empty(), Option::<&str>::None, ) .map_err(|e| Error::Nix { -- 2.46.0 From 60c78889376fb81b1f62ef569bc2f6e2ab9864be Mon Sep 17 00:00:00 2001 From: Jake Hillion Date: Tue, 17 May 2022 15:25:14 +0100 Subject: [PATCH 2/2] increased logging and accounted for missing /tmp --- src/void.rs | 46 +++++++++++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/src/void.rs b/src/void.rs index 1b02e92..130148d 100644 --- a/src/void.rs +++ b/src/void.rs @@ -1,9 +1,10 @@ -use log::{debug, error}; +use log::{debug, error, info, trace}; use crate::clone::{clone3, CloneArgs, CloneFlags}; use crate::{Error, Result}; use std::collections::{HashMap, HashSet}; +use std::env; use std::fmt; use std::fs; use std::io::Write; @@ -102,15 +103,23 @@ impl VoidBuilder { })?; let result = { + debug!("voiding user namespace..."); self.void_user_namespace(parent_uid, parent_gid)?; // first to regain full capabilities + debug!("voiding file descriptors..."); self.void_file_descriptors()?; + debug!("voiding ipc namespace..."); self.void_ipc_namespace()?; + debug!("voiding uts namespace..."); self.void_uts_namespace()?; + debug!("voiding network namespace..."); self.void_network_namespace()?; + debug!("voiding pid namespace..."); self.void_pid_namespace()?; + debug!("voiding mount namespace..."); self.void_mount_namespace()?; + debug!("voiding cgroup namespace..."); self.void_cgroup_namespace()?; Ok::<(), Error>(()) @@ -120,6 +129,7 @@ impl VoidBuilder { error!("error preparing void: {}", e); std::process::exit(-1) } else { + info!("successfully prepared void"); std::process::exit(child_fn()) } } @@ -188,7 +198,7 @@ impl VoidBuilder { * unavailable after unmounting the old root. */ fn void_mount_namespace(&self) -> Result<()> { - // change the propagation type of the old root to private + trace!("changing the propagation type of the old root to private"); mount( Option::<&str>::None, "/", @@ -201,10 +211,21 @@ impl VoidBuilder { src: e, })?; - // create and consume a tmpdir to mount a tmpfs into - let new_root = tempfile::tempdir()?.into_path(); + trace!("creating tmpdir for new root"); + let tmp_base = { + let env_dir = env::temp_dir(); + if env_dir.exists() { + env_dir + } else { + debug!("env_dir does not exist, assuming `/` as the base"); + "/".into() + } + }; - // mount a tmpfs as the new root + // consume so it does not attempt to delete a folder which no longer exists + let new_root = tempfile::tempdir_in(tmp_base)?.into_path(); + + trace!("mounting a new root tmpfs at `{:?}`", &new_root); mount( Some("tmpfs"), &new_root, @@ -217,13 +238,12 @@ impl VoidBuilder { src: e, })?; - // prepare a subdirectory to pivot the old root into - let old_root = new_root.join("old_root/"); - debug!("new_root: {:?}; put_old: {:?}", &new_root, &old_root); - fs::create_dir(&old_root)?; + let put_old = new_root.join("old_root/"); + debug!("new_root: {:?}; put_old: {:?}", &new_root, &put_old); + fs::create_dir_all(&put_old)?; - // pivot the old root into a subdirectory of the new root - pivot_root(&new_root, &old_root).map_err(|e| Error::Nix { + trace!("pivoting old root into a subdirectory of new root"); + pivot_root(&new_root, &put_old).map_err(|e| Error::Nix { msg: "pivot_root", src: e, })?; @@ -231,10 +251,10 @@ impl VoidBuilder { let new_root = PathBuf::from("/"); let old_root = PathBuf::from("/old_root/"); - // chdir after + trace!("changing root directory to new root"); std::env::set_current_dir(&new_root)?; - // mount paths before unmounting old_root + trace!("creating bind mounts before unmounting"); for (src, dst) in &self.mounts { let mut src = old_root.join(src.strip_prefix("/").unwrap_or(src)); let dst = new_root.join(dst.strip_prefix("/").unwrap_or(dst)); -- 2.46.0