bunpen: proof-of-concept mount namespacing
This commit is contained in:
@@ -1,13 +1,21 @@
|
||||
// vim: set shiftwidth=2 :
|
||||
use fs;
|
||||
use io;
|
||||
use log;
|
||||
use os;
|
||||
use rt;
|
||||
use rtext;
|
||||
use unix;
|
||||
|
||||
export fn namespace_restrict(what: *resources) void = {
|
||||
let proc_fd = rt::open("/proc", rt::O_PATH | rt::O_CLOEXEC, 0)!;
|
||||
let proc_fs = os::dirfdopen(proc_fd);
|
||||
// unshare as much as possible, by default:
|
||||
let what_to_unshare =
|
||||
rtext::CLONE_NEWCGROUP |
|
||||
rtext::CLONE_NEWIPC |
|
||||
rtext::CLONE_NEWNET |
|
||||
rtext::CLONE_NEWNS |
|
||||
rtext::CLONE_NEWUSER |
|
||||
rtext::CLONE_NEWUTS
|
||||
;
|
||||
@@ -15,8 +23,58 @@ export fn namespace_restrict(what: *resources) void = {
|
||||
log::println("namespace: permit net");
|
||||
what_to_unshare &= ~rtext::CLONE_NEWNET;
|
||||
};
|
||||
|
||||
log::printfln("namespace: unshare {}", what_to_unshare);
|
||||
rtext::unshare(what_to_unshare)!;
|
||||
// TODO: LONE_NEWNS (mount namespace)
|
||||
// CLONE_NEWPID (might not work without forking to also become reaper)
|
||||
|
||||
// before mounting anything, set up the uids and gids in this namespace.
|
||||
// without this, everything shows up as 65534 a.k.a. 'nobody' a.k.a. 'overflow',
|
||||
// and `mkdir` will return EOVERFLOW.
|
||||
// all this does is make it so that namespace operations under uid 1000 are
|
||||
// mapped to non-ns ops by the same user, and vice-versa
|
||||
write_uid_map(proc_fs);
|
||||
|
||||
rt::mount("tmpfs", "/tmp", &['t': u8, 'm', 'p', 'f', 's', 0]: *const u8, rtext::MS_NODEV | rtext::MS_NOSUID, null)!;
|
||||
|
||||
// chroot to `/tmp`, with the old root being placed at `/tmp/oldroot` (i.e. /oldroot)
|
||||
check_error("cd /tmp", os::chdir("/tmp"));
|
||||
check_error("mkdir /tmp/oldroot", rt::mkdir(&['o': u8, 'l', 'd', 'r', 'o', 'o', 't', 0]: *const u8, 0o755));
|
||||
rtext::pivot_root("/tmp", "oldroot")!;
|
||||
check_error("cd /", os::chdir("/"));
|
||||
|
||||
// chroot back into `/oldroot`.
|
||||
// TODO: we should rather chroot into `/newroot`, after mounting everything
|
||||
// there. this is just a proof-of-concept
|
||||
check_error("cd /oldroot", os::chdir("/oldroot"));
|
||||
rtext::pivot_root("/oldroot", ".")!;
|
||||
check_error("cd /", os::chdir("/"));
|
||||
|
||||
// TODO: CLONE_NEWPID (might not work without forking to also become reaper)
|
||||
};
|
||||
|
||||
fn check_error(op: str, c: (void | fs::error | rt::errno)) void = {
|
||||
match (c) {
|
||||
case void => void;
|
||||
case let e: rt::errno => log::fatalf("{}: {}: {}", op, rt::errname(e), rt::strerror(e));
|
||||
case let e: fs::error => log::fatalf("{}: {}", op, fs::strerror(e));
|
||||
};
|
||||
};
|
||||
|
||||
// fn write_uid_map(proc_fd: int) void = {
|
||||
// // let uid_fd = rt::open("/proc/self/uid_map", rt::O_RDWR | rt::O_CLOEXEC, 0)!;
|
||||
// let uid_fd = rt::openat2(proc_fd, "self/uid_map", rt::open_how {
|
||||
// flags: rt::O_RDWR | rt::O_CLOEXEC, ...
|
||||
// })!;
|
||||
// io::write(uid_fd, &['1': u8, '0', '0', '0', ' ', '0', ' ', '1', 0])!;
|
||||
// };
|
||||
|
||||
fn write_uid_map(proc_fs: *fs::fs) void = {
|
||||
let uid_fd = fs::open(proc_fs, "self/uid_map", fs::flag::RDWR)!;
|
||||
io::write(uid_fd, &['1': u8, '0', '0', '0', ' ', '1', '0', '0', '0', ' ', '1', '\n', 0])!;
|
||||
|
||||
let setgroups_fd = fs::open(proc_fs, "self/setgroups", fs::flag::RDWR)!;
|
||||
io::write(setgroups_fd, &['d': u8, 'e', 'n', 'y', '\n', 0])!;
|
||||
|
||||
let gid_fd = fs::open(proc_fs, "self/gid_map", fs::flag::RDWR)!;
|
||||
io::write(gid_fd, &['1': u8, '0', '0', ' ', '1', '0', '0', ' ', '1', '\n', 0])!;
|
||||
};
|
||||
|
28
pkgs/additional/bunpen/rtext/mount.ha
Normal file
28
pkgs/additional/bunpen/rtext/mount.ha
Normal file
@@ -0,0 +1,28 @@
|
||||
// vim: set shiftwidth=2 :
|
||||
|
||||
export const MS_RDONLY: u64 = 1;
|
||||
export const MS_NOSUID: u64 = 2;
|
||||
export const MS_NODEV: u64 = 4;
|
||||
export const MS_NOEXEC: u64 = 8;
|
||||
export const MS_SYNCHRONOUS: u64 = 16;
|
||||
export const MS_REMOUNT: u64 = 32;
|
||||
export const MS_MANDLOCK: u64 = 64;
|
||||
export const MS_DIRSYNC: u64 = 128;
|
||||
export const MS_NOSYMFOLLOW: u64 = 256;
|
||||
export const MS_NOATIME: u64 = 1024;
|
||||
export const MS_NODIRATIME: u64 = 2048;
|
||||
export const MS_BIND: u64 = 4096;
|
||||
export const MS_MOVE: u64 = 8192;
|
||||
export const MS_REC: u64 = 16384;
|
||||
export const MS_VERBOSE: u64 = 32768;
|
||||
export const MS_SILENT: u64 = 32768;
|
||||
export const MS_POSIXACL: u64 =(1<<16);
|
||||
export const MS_UNBINDABLE: u64 =(1<<17);
|
||||
export const MS_PRIVATE: u64 =(1<<18);
|
||||
export const MS_SLAVE: u64 =(1<<19);
|
||||
export const MS_SHARED: u64 =(1<<20);
|
||||
export const MS_RELATIME: u64 =(1<<21);
|
||||
export const MS_KERNMOUNT: u64 =(1<<22);
|
||||
export const MS_I_VERSION: u64 =(1<<23);
|
||||
export const MS_STRICTATIME: u64 =(1<<24);
|
||||
export const MS_LAZYTIME: u64 =(1<<25);
|
Reference in New Issue
Block a user