bunpen: clean up mount namespacing so that i could bind any directory -- including /tmp
This commit is contained in:
@@ -43,31 +43,38 @@ export fn namespace_restrict(what: *resources) void = {
|
|||||||
// namespace, but not vice versa:
|
// namespace, but not vice versa:
|
||||||
rtext::check_error("reconfigure / as MS_SLAVE", rtext::mount("/", "/", "", rtext::MS_SLAVE | rtext::MS_REC, null));
|
rtext::check_error("reconfigure / as MS_SLAVE", rtext::mount("/", "/", "", rtext::MS_SLAVE | rtext::MS_REC, null));
|
||||||
|
|
||||||
// setup a new root in `/tmp`, mount the desired paths into it, and then pivot into it.
|
// in order to mount ANY directory from the old root into the new root,
|
||||||
|
// they have to be totally disparate. if we kept the old root at / and the new
|
||||||
|
// root at /tmp, then we couldn't bind `/tmp`.
|
||||||
|
//
|
||||||
|
// 1. pivoting _anywhere_ allows us to put the old root at `old`.
|
||||||
|
// i use `/tmp` here, just because that's how bubblewrap does it.
|
||||||
|
// 2. create a new rootfs at `new` and bind stuff into it.
|
||||||
|
// 3. then pivot a 2nd time, into `new` (and drop `old` altogether)
|
||||||
|
|
||||||
rtext::check_error("mount -t tmpfs tmpfs /tmp", rtext::mount("tmpfs", "/tmp", "tmpfs", 0, null));
|
rtext::check_error("mount -t tmpfs tmpfs /tmp", rtext::mount("tmpfs", "/tmp", "tmpfs", 0, null));
|
||||||
|
|
||||||
// TODO: mount the paths the user asks for, but until then hardcode stuff:
|
|
||||||
rtext::check_error("mkdir /tmp/bin", rt::mkdir("/tmp/bin", 0o755));
|
|
||||||
rtext::check_error("mount /bin /tmp/bin", rtext::mount("/bin", "/tmp/bin", "", rtext::MS_BIND | rtext::MS_REC, null));
|
|
||||||
// rtext::check_error("mkdir /tmp/dev", rt::mkdir("/tmp/dev", 0o755));
|
|
||||||
// rtext::check_error("mount /dev /tmp/dev", rtext::mount("/dev", "/tmp/dev", "", rtext::MS_BIND | rtext::MS_REC, null));
|
|
||||||
// rtext::check_error("mkdir /tmp/etc", rt::mkdir("/tmp/etc", 0o755));
|
|
||||||
// rtext::check_error("mount /etc /tmp/etc", rtext::mount("/etc", "/tmp/etc", "", rtext::MS_BIND | rtext::MS_REC, null));
|
|
||||||
rtext::check_error("mkdir /tmp/nix", rt::mkdir("/tmp/nix", 0o755));
|
|
||||||
rtext::check_error("mount /nix /tmp/nix", rtext::mount("/nix", "/tmp/nix", "", rtext::MS_BIND | rtext::MS_REC, null));
|
|
||||||
// rtext::check_error("mkdir /tmp/proc", rt::mkdir("/tmp/proc", 0o755));
|
|
||||||
// rtext::check_error("mount /proc /tmp/proc", rtext::mount("/proc", "/tmp/proc", "", rtext::MS_BIND | rtext::MS_REC, null));
|
|
||||||
// rtext::check_error("mkdir /tmp/run", rt::mkdir("/tmp/run", 0o755));
|
|
||||||
// rtext::check_error("mount /run /tmp/run", rtext::mount("/run", "/tmp/run", "", rtext::MS_BIND | rtext::MS_REC, null));
|
|
||||||
// rtext::check_error("mkdir /tmp/sys", rt::mkdir("/tmp/sys", 0o755));
|
|
||||||
// rtext::check_error("mount /sys /tmp/sys", rtext::mount("/sys", "/tmp/sys", "", rtext::MS_BIND | rtext::MS_REC, null));
|
|
||||||
// rtext::check_error("mkdir /tmp/usr", rt::mkdir("/tmp/usr", 0o755));
|
|
||||||
// rtext::check_error("mount /usr /tmp/usr", rtext::mount("/usr", "/tmp/usr", "", rtext::MS_BIND | rtext::MS_REC, null));
|
|
||||||
// rtext::check_error("mkdir /tmp/var", rt::mkdir("/tmp/var", 0o755));
|
|
||||||
// rtext::check_error("mount /var /tmp/var", rtext::mount("/var", "/tmp/var", "", rtext::MS_BIND | rtext::MS_REC, null));
|
|
||||||
|
|
||||||
rtext::check_error("cd /tmp", os::chdir("/tmp"));
|
rtext::check_error("cd /tmp", os::chdir("/tmp"));
|
||||||
|
rtext::check_error("mkdir old", rt::mkdir("old", 0o755));
|
||||||
|
rtext::check_error("pivot_root . old", rtext::pivot_root(".", "old"));
|
||||||
|
rtext::check_error("cd /", os::chdir("/"));
|
||||||
|
// now we have `/`, empty except for the old rootfs available at `/old`
|
||||||
|
|
||||||
|
// prepare a new rootfs. it has to be its own mount (tmpfs), not just a dir.
|
||||||
|
rtext::check_error("mkdir new", rt::mkdir("new", 0o755));
|
||||||
|
rtext::check_error("mount -t tmpfs tmpfs new", rtext::mount("tmpfs", "new", "tmpfs", 0, null));
|
||||||
|
|
||||||
|
// bind old/$dir to new/$dir for every `dir` we want available in the sandbox:
|
||||||
|
// TODO: mount the paths the user asks for, but until then hardcode stuff.
|
||||||
|
rtext::check_error("mkdir new/bin", rt::mkdir("new/bin", 0o755));
|
||||||
|
rtext::check_error("mount old/bin new/bin", rtext::mount("old/bin", "new/bin", "", rtext::MS_BIND | rtext::MS_REC, null));
|
||||||
|
rtext::check_error("mkdir new/nix", rt::mkdir("new/nix", 0o755));
|
||||||
|
rtext::check_error("mount old/nix new/nix", rtext::mount("old/nix", "new/nix", "", rtext::MS_BIND | rtext::MS_REC, null));
|
||||||
|
|
||||||
|
// pivot into the new rootfs
|
||||||
|
rtext::check_error("cd new", os::chdir("new"));
|
||||||
rtext::check_error("pivot_root . .", rtext::pivot_root(".", "."));
|
rtext::check_error("pivot_root . .", rtext::pivot_root(".", "."));
|
||||||
|
// drop the old rootfs. weird idiom, but documented in `man 2 pivot_root`.
|
||||||
rtext::check_error("umount .", rt::umount2(".", rtext::MNT_DETACH));
|
rtext::check_error("umount .", rt::umount2(".", rtext::MNT_DETACH));
|
||||||
rtext::check_error("cd /", os::chdir("/"));
|
rtext::check_error("cd /", os::chdir("/"));
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user