1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
|
use nix::{
mount::{self, MntFlags, MsFlags},
sched::CloneFlags,
unistd::{self, Gid, Pid, Uid},
};
use rebel_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<F>(flags: CloneFlags, f: F) -> nix::Result<Pid>
where
F: FnOnce(),
{
assert!(flags.contains(CloneFlags::CLONE_NEWNS) || !flags.contains(CloneFlags::CLONE_NEWPID));
clone::spawn(Some(flags), || {
if flags.contains(CloneFlags::CLONE_NEWPID) {
mount_proc();
}
f()
})
}
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(())
}
|