diff options
author | Matthias Schiffer <mschiffer@universe-factory.net> | 2021-10-25 00:19:45 +0200 |
---|---|---|
committer | Matthias Schiffer <mschiffer@universe-factory.net> | 2021-10-25 00:19:45 +0200 |
commit | 34ac18d20c13a78914d447fee83204811a27b1e4 (patch) | |
tree | 56763d4ea46927105fcc6a71e03d5bd75a6947a6 /crates/runner/src/ns.rs | |
parent | a1a185370da27f2cc3df84d3a8d7141f9ce7db16 (diff) | |
download | rebel-34ac18d20c13a78914d447fee83204811a27b1e4.tar rebel-34ac18d20c13a78914d447fee83204811a27b1e4.zip |
Move runner into separate crate
Diffstat (limited to 'crates/runner/src/ns.rs')
-rw-r--r-- | crates/runner/src/ns.rs | 84 |
1 files changed, 84 insertions, 0 deletions
diff --git a/crates/runner/src/ns.rs b/crates/runner/src/ns.rs new file mode 100644 index 0000000..a075931 --- /dev/null +++ b/crates/runner/src/ns.rs @@ -0,0 +1,84 @@ +use nix::{ + mount::{self, MntFlags, MsFlags}, + sched::CloneFlags, + unistd::{self, Gid, Pid, Uid}, +}; + +use common::error::*; + +use super::util::clone; + +pub fn mount_proc() { + mount::mount::<_, _, _, str>(Some("proc"), "/proc", Some("proc"), MsFlags::empty(), None) + .expect("Failed to mount /proc"); +} + +pub fn setup_userns(inner_uid: Uid, inner_gid: Gid, outer_uid: Uid, outer_gid: Gid) { + std::fs::write("/proc/self/setgroups", "deny").expect("Failed to write /proc/self/setgroups"); + std::fs::write( + "/proc/self/uid_map", + &format!("{} {} 1", inner_uid, outer_uid), + ) + .expect("Failed to write /proc/self/uid_map"); + std::fs::write( + "/proc/self/gid_map", + &format!("{} {} 1", inner_gid, outer_gid), + ) + .expect("Failed to write /proc/self/gid_map"); +} + +pub unsafe fn spawn<T, F>(flags: CloneFlags, arg: T, f: F) -> nix::Result<(Pid, T)> +where + F: FnOnce(T), +{ + assert!(flags.contains(CloneFlags::CLONE_NEWNS) || !flags.contains(CloneFlags::CLONE_NEWPID)); + + clone::spawn(Some(flags), arg, |arg| { + if flags.contains(CloneFlags::CLONE_NEWPID) { + mount_proc(); + } + f(arg) + }) +} + +pub fn pivot_root(path: &str) { + (|| -> Result<()> { + unistd::chdir(path).context("chdir()")?; + mount::mount::<_, _, str, str>(Some("/proc"), "proc", None, MsFlags::MS_BIND, None) + .context("Failed to bind mount /proc")?; + unistd::pivot_root(".", ".").context("pivot_root()")?; + mount::umount2(".", MntFlags::MNT_DETACH).context("umount2()")?; + unistd::chdir("/").context("chdir(\"/\")")?; + Ok(()) + })() + .expect("Failed to pivot root"); +} + +pub fn container_mounts() -> Result<()> { + mount::mount( + Some("tmp"), + "/tmp", + Some("tmpfs"), + MsFlags::MS_NODEV | MsFlags::MS_NOSUID, + Some("mode=1777,size=1048576k"), + ) + .context("Failed to mount /tmp")?; + mount::mount( + Some("devpts"), + "/dev/pts", + Some("devpts"), + MsFlags::MS_NOSUID | MsFlags::MS_NOEXEC, + Some("newinstance,ptmxmode=0666,mode=0620"), + ) + .context("Failed to mount /dev/pts")?; + mount::mount( + Some("shm"), + "/dev/shm", + Some("tmpfs"), + MsFlags::MS_NOSUID | MsFlags::MS_NOEXEC | MsFlags::MS_NODEV, + Some("mode=1777,size=65536k"), + ) + .context("Failed to mount /dev/shm")?; + + Ok(()) +} |