bunpen: move rtext:: -> rt::ext::
This commit is contained in:
@@ -7,7 +7,7 @@ use os;
|
||||
use path;
|
||||
use restrict;
|
||||
use rt;
|
||||
use rtext;
|
||||
use rt::ext;
|
||||
|
||||
// the user requested to see help.
|
||||
export type help = !void;
|
||||
|
@@ -5,7 +5,7 @@ use log;
|
||||
use log::tree;
|
||||
use restrict;
|
||||
use rt;
|
||||
use rtext;
|
||||
use rt::ext;
|
||||
use strings;
|
||||
use os;
|
||||
use os::exec;
|
||||
@@ -18,7 +18,7 @@ fn do_exec(path: str, args: []str) (os::exec::error | void) = {
|
||||
log::printfln("exec ({}): {}", path, joined);
|
||||
};
|
||||
|
||||
errors::ext::check("exec", rtext::execve(path, args, os::getenvs()));
|
||||
errors::ext::check("exec", rt::ext::execve(path, args, os::getenvs()));
|
||||
|
||||
// XXX: os::exec::exec offers no way to preserve argv0, but it does
|
||||
// work if you don't care about that:
|
||||
@@ -46,7 +46,7 @@ export fn main() void = {
|
||||
case let other: config::cli_request => yield other;
|
||||
};
|
||||
|
||||
rtext::no_new_privs()!;
|
||||
rt::ext::no_new_privs()!;
|
||||
restrict::namespace_restrict(&req.resources);
|
||||
// XXX: landlock prevents other sandboxers like `bwrap` from executing,
|
||||
// because it forbids all future `mount` syscalls. so don't landlock.
|
||||
|
@@ -5,35 +5,35 @@ use log;
|
||||
use os;
|
||||
use path;
|
||||
use rt;
|
||||
use rtext;
|
||||
use rt::ext;
|
||||
|
||||
fn access_fs_roughly_read() rtext::landlock_access_fs_set = return
|
||||
rtext::landlock_access_fs::EXECUTE |
|
||||
rtext::landlock_access_fs::READ_FILE |
|
||||
rtext::landlock_access_fs::READ_DIR
|
||||
fn access_fs_roughly_read() rt::ext::landlock_access_fs_set = return
|
||||
rt::ext::landlock_access_fs::EXECUTE |
|
||||
rt::ext::landlock_access_fs::READ_FILE |
|
||||
rt::ext::landlock_access_fs::READ_DIR
|
||||
;
|
||||
fn access_fs_roughly_write() rtext::landlock_access_fs_set = return
|
||||
rtext::landlock_access_fs::WRITE_FILE |
|
||||
rtext::landlock_access_fs::REMOVE_DIR |
|
||||
rtext::landlock_access_fs::REMOVE_FILE |
|
||||
rtext::landlock_access_fs::MAKE_CHAR |
|
||||
rtext::landlock_access_fs::MAKE_DIR |
|
||||
rtext::landlock_access_fs::MAKE_REG |
|
||||
rtext::landlock_access_fs::MAKE_SOCK |
|
||||
rtext::landlock_access_fs::MAKE_FIFO |
|
||||
rtext::landlock_access_fs::MAKE_BLOCK |
|
||||
rtext::landlock_access_fs::MAKE_SYM |
|
||||
rtext::landlock_access_fs::REFER |
|
||||
rtext::landlock_access_fs::TRUNCATE |
|
||||
rtext::landlock_access_fs::IOCTL_DEV
|
||||
fn access_fs_roughly_write() rt::ext::landlock_access_fs_set = return
|
||||
rt::ext::landlock_access_fs::WRITE_FILE |
|
||||
rt::ext::landlock_access_fs::REMOVE_DIR |
|
||||
rt::ext::landlock_access_fs::REMOVE_FILE |
|
||||
rt::ext::landlock_access_fs::MAKE_CHAR |
|
||||
rt::ext::landlock_access_fs::MAKE_DIR |
|
||||
rt::ext::landlock_access_fs::MAKE_REG |
|
||||
rt::ext::landlock_access_fs::MAKE_SOCK |
|
||||
rt::ext::landlock_access_fs::MAKE_FIFO |
|
||||
rt::ext::landlock_access_fs::MAKE_BLOCK |
|
||||
rt::ext::landlock_access_fs::MAKE_SYM |
|
||||
rt::ext::landlock_access_fs::REFER |
|
||||
rt::ext::landlock_access_fs::TRUNCATE |
|
||||
rt::ext::landlock_access_fs::IOCTL_DEV
|
||||
;
|
||||
fn access_fs_roughly_rw() rtext::landlock_access_fs_set = return access_fs_roughly_read() | access_fs_roughly_write();
|
||||
fn access_file() rtext::landlock_access_fs_set = return
|
||||
rtext::landlock_access_fs::EXECUTE |
|
||||
rtext::landlock_access_fs::WRITE_FILE |
|
||||
rtext::landlock_access_fs::READ_FILE |
|
||||
rtext::landlock_access_fs::TRUNCATE |
|
||||
rtext::landlock_access_fs::IOCTL_DEV
|
||||
fn access_fs_roughly_rw() rt::ext::landlock_access_fs_set = return access_fs_roughly_read() | access_fs_roughly_write();
|
||||
fn access_file() rt::ext::landlock_access_fs_set = return
|
||||
rt::ext::landlock_access_fs::EXECUTE |
|
||||
rt::ext::landlock_access_fs::WRITE_FILE |
|
||||
rt::ext::landlock_access_fs::READ_FILE |
|
||||
rt::ext::landlock_access_fs::TRUNCATE |
|
||||
rt::ext::landlock_access_fs::IOCTL_DEV
|
||||
;
|
||||
|
||||
fn allow_path_fd(ruleset_fd: u64, path_fd: i32) (void | fs::error | rt::errno) = {
|
||||
@@ -46,7 +46,7 @@ fn allow_path_fd(ruleset_fd: u64, path_fd: i32) (void | fs::error | rt::errno) =
|
||||
access = access & access_file();
|
||||
};
|
||||
|
||||
rtext::landlock_add_rule(ruleset_fd, &rtext::landlock_path_beneath_attr {
|
||||
rt::ext::landlock_add_rule(ruleset_fd, &rt::ext::landlock_path_beneath_attr {
|
||||
allowed_access = access,
|
||||
parent_fd = path_fd,
|
||||
})?;
|
||||
@@ -58,25 +58,25 @@ fn allow_path(ruleset_fd: u64, path_str: str) (void | fs::error | rt::errno) = {
|
||||
};
|
||||
|
||||
export fn landlock_restrict(what: *resources) void = {
|
||||
let abi = rtext::landlock_create_ruleset(null, rtext::landlock_create_ruleset_flag::VERSION)!;
|
||||
let abi = rt::ext::landlock_create_ruleset(null, rt::ext::landlock_create_ruleset_flag::VERSION)!;
|
||||
log::printfln("[landlock] found version {}", abi);
|
||||
|
||||
// determine the access modes we can ask this kernel to restrict on:
|
||||
let ruleset_attr = rtext::landlock_ruleset_attr {
|
||||
let ruleset_attr = rt::ext::landlock_ruleset_attr {
|
||||
handled_access_fs = access_fs_roughly_rw(),
|
||||
handled_access_net = rtext::landlock_access_net::BIND_TCP | rtext::landlock_access_net::CONNECT_TCP,
|
||||
handled_access_net = rt::ext::landlock_access_net::BIND_TCP | rt::ext::landlock_access_net::CONNECT_TCP,
|
||||
};
|
||||
if (abi == 1) {
|
||||
ruleset_attr.handled_access_fs &= ~rtext::landlock_access_fs::REFER;
|
||||
ruleset_attr.handled_access_fs &= ~rt::ext::landlock_access_fs::REFER;
|
||||
};
|
||||
if (abi <= 2) {
|
||||
ruleset_attr.handled_access_fs &= ~rtext::landlock_access_fs::TRUNCATE;
|
||||
ruleset_attr.handled_access_fs &= ~rt::ext::landlock_access_fs::TRUNCATE;
|
||||
};
|
||||
if (abi <= 3) {
|
||||
ruleset_attr.handled_access_net &= ~(rtext::landlock_access_net::BIND_TCP | rtext::landlock_access_net::CONNECT_TCP);
|
||||
ruleset_attr.handled_access_net &= ~(rt::ext::landlock_access_net::BIND_TCP | rt::ext::landlock_access_net::CONNECT_TCP);
|
||||
};
|
||||
if (abi <= 4) {
|
||||
ruleset_attr.handled_access_fs &= ~rtext::landlock_access_fs::IOCTL_DEV;
|
||||
ruleset_attr.handled_access_fs &= ~rt::ext::landlock_access_fs::IOCTL_DEV;
|
||||
};
|
||||
|
||||
if (what.net) {
|
||||
@@ -85,7 +85,7 @@ export fn landlock_restrict(what: *resources) void = {
|
||||
ruleset_attr.handled_access_net = 0;
|
||||
}; // XXX: `what.net` only affects TCP. UDP, and ICMP remain possible always
|
||||
|
||||
let ruleset_fd = rtext::landlock_create_ruleset(&ruleset_attr)!;
|
||||
let ruleset_fd = rt::ext::landlock_create_ruleset(&ruleset_attr)!;
|
||||
|
||||
for (let pathbuf .. what.paths) {
|
||||
let pathstr = path::string(&pathbuf);
|
||||
@@ -93,7 +93,7 @@ export fn landlock_restrict(what: *resources) void = {
|
||||
errors::ext::swallow("[landlock/path] omitting from sandbox: failed to add path", allow_path(ruleset_fd, pathstr));
|
||||
};
|
||||
|
||||
rtext::landlock_restrict_self(ruleset_fd)!;
|
||||
rt::ext::landlock_restrict_self(ruleset_fd)!;
|
||||
|
||||
log::println("landlock restrictions activated");
|
||||
};
|
||||
|
@@ -8,7 +8,7 @@ use os;
|
||||
use os::exec;
|
||||
use path;
|
||||
use rt;
|
||||
use rtext;
|
||||
use rt::ext;
|
||||
use strings;
|
||||
use unix;
|
||||
|
||||
@@ -20,25 +20,25 @@ export fn namespace_restrict(what: *resources) void = {
|
||||
|
||||
// unshare as much as possible, by default:
|
||||
let what_to_unshare =
|
||||
rtext::clone_flag::NEWCGROUP |
|
||||
rtext::clone_flag::NEWIPC |
|
||||
rtext::clone_flag::NEWNET |
|
||||
rtext::clone_flag::NEWNS |
|
||||
rtext::clone_flag::NEWPID |
|
||||
rtext::clone_flag::NEWUSER |
|
||||
rtext::clone_flag::NEWUTS
|
||||
rt::ext::clone_flag::NEWCGROUP |
|
||||
rt::ext::clone_flag::NEWIPC |
|
||||
rt::ext::clone_flag::NEWNET |
|
||||
rt::ext::clone_flag::NEWNS |
|
||||
rt::ext::clone_flag::NEWPID |
|
||||
rt::ext::clone_flag::NEWUSER |
|
||||
rt::ext::clone_flag::NEWUTS
|
||||
;
|
||||
if (what.net) {
|
||||
log::println("[namespace] keeping net namespace");
|
||||
what_to_unshare &= ~rtext::clone_flag::NEWNET;
|
||||
what_to_unshare &= ~rt::ext::clone_flag::NEWNET;
|
||||
};
|
||||
if (what.pid) {
|
||||
log::println("[namespace] keeping pid namespace");
|
||||
what_to_unshare &= ~rtext::clone_flag::NEWPID;
|
||||
what_to_unshare &= ~rt::ext::clone_flag::NEWPID;
|
||||
};
|
||||
|
||||
log::printfln("[namespace] unshare {}", what_to_unshare: u64);
|
||||
rtext::unshare(what_to_unshare)!;
|
||||
rt::ext::unshare(what_to_unshare)!;
|
||||
|
||||
// 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',
|
||||
@@ -92,7 +92,7 @@ fn fork_and_propagate() (void | os::exec::error) = {
|
||||
fn isolate_paths(paths: []path::buffer) void = {
|
||||
// allow new mounts to propagate from the parent namespace into the child
|
||||
// namespace, but not vice versa:
|
||||
errors::ext::check("[namespace] reconfigure / as MS_SLAVE", rtext::mount("/", "/", "", rtext::mount_flag::SLAVE | rtext::mount_flag::REC, null));
|
||||
errors::ext::check("[namespace] reconfigure / as MS_SLAVE", rt::ext::mount("/", "/", "", rt::ext::mount_flag::SLAVE | rt::ext::mount_flag::REC, null));
|
||||
|
||||
// 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
|
||||
@@ -103,16 +103,16 @@ fn isolate_paths(paths: []path::buffer) void = {
|
||||
// 2. create a new rootfs at `new` and bind stuff into it.
|
||||
// 3. then pivot a 2nd time, into `new` (and drop `old` altogether)
|
||||
|
||||
errors::ext::check("[namespace] mount -t tmpfs tmpfs /tmp", rtext::mount("tmpfs", "/tmp", "tmpfs", rtext::mount_flag::NODEV | rtext::mount_flag::NOSUID, null));
|
||||
errors::ext::check("[namespace] mount -t tmpfs tmpfs /tmp", rt::ext::mount("tmpfs", "/tmp", "tmpfs", rt::ext::mount_flag::NODEV | rt::ext::mount_flag::NOSUID, null));
|
||||
|
||||
pivot_into("/tmp", "old");
|
||||
// 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.
|
||||
errors::ext::check("[namespace] mkdir new", rt::mkdir("new", 0o755));
|
||||
errors::ext::check("[namespace] mount -t tmpfs tmpfs new", rtext::mount("tmpfs", "new", "tmpfs", 0, null));
|
||||
// errors::ext::check("[namespace] mount -t tmpfs tmpfs new", rtext::mount("tmpfs", "new", "tmpfs", rtext::mount_flag::NODEV | rtext::mount_flag::NOSUID, null));
|
||||
// errors::ext::check("[namespace] mount -o rbind new new", rtext::mount("new", "new", "", rtext::mount_flag::BIND | rtext::mount_flag::REC, null));
|
||||
errors::ext::check("[namespace] mount -t tmpfs tmpfs new", rt::ext::mount("tmpfs", "new", "tmpfs", 0, null));
|
||||
// errors::ext::check("[namespace] mount -t tmpfs tmpfs new", rt::ext::mount("tmpfs", "new", "tmpfs", rt::ext::mount_flag::NODEV | rt::ext::mount_flag::NOSUID, null));
|
||||
// errors::ext::check("[namespace] mount -o rbind new new", rt::ext::mount("new", "new", "", rt::ext::mount_flag::BIND | rt::ext::mount_flag::REC, null));
|
||||
|
||||
// try to mount a new /proc.
|
||||
// - this is "safe" because we're not doing anything
|
||||
@@ -127,14 +127,14 @@ fn isolate_paths(paths: []path::buffer) void = {
|
||||
// but in practice there are namespacing bugs at least as recently as 2021:
|
||||
// <https://github.com/opencontainers/runc/issues/2826#issuecomment-915683044>
|
||||
errors::ext::swallow("[namespace] mkdir new/proc", rt::mkdir("new/proc", 0o755));
|
||||
errors::ext::swallow("[namespace] mount /new/proc", rtext::mount(
|
||||
"proc", "new/proc", "proc", rtext::mount_flag::NOSUID | rtext::mount_flag::NOEXEC | rtext::mount_flag::NODEV, null
|
||||
errors::ext::swallow("[namespace] mount /new/proc", rt::ext::mount(
|
||||
"proc", "new/proc", "proc", rt::ext::mount_flag::NOSUID | rt::ext::mount_flag::NOEXEC | rt::ext::mount_flag::NODEV, null
|
||||
));
|
||||
|
||||
|
||||
// provide a new `/tmp` too.
|
||||
errors::ext::swallow("[namespace] mkdir new/tmp", rt::mkdir("new/tmp", 0o777));
|
||||
errors::ext::swallow("[namespace] mount -t tmpfs tmpfs new/tmp", rtext::mount("tmpfs", "new/tmp", "tmpfs", 0, null));
|
||||
errors::ext::swallow("[namespace] mount -t tmpfs tmpfs new/tmp", rt::ext::mount("tmpfs", "new/tmp", "tmpfs", 0, null));
|
||||
|
||||
// bind all the user-requested paths from `old/$p` into `new/$p`.
|
||||
// use the `dirfd` abstraction so that paths meant for `old` can't crawl out
|
||||
@@ -232,8 +232,8 @@ fn bind_leaf(old_fs: *fs::fs, new_fs: *fs::fs, user_path: *path::buffer) void =
|
||||
};
|
||||
|
||||
log::printfln("[namespace/bind] mount {} {}", path::string(&old_pathbuf), path::string(&new_pathbuf));
|
||||
errors::ext::swallow("[namespace/bind] bind_leaf: mount", rtext::mount(
|
||||
path::string(&old_pathbuf), path::string(&new_pathbuf), "", rtext::mount_flag::BIND | rtext::mount_flag::REC, null
|
||||
errors::ext::swallow("[namespace/bind] bind_leaf: mount", rt::ext::mount(
|
||||
path::string(&old_pathbuf), path::string(&new_pathbuf), "", rt::ext::mount_flag::BIND | rt::ext::mount_flag::REC, null
|
||||
));
|
||||
};
|
||||
|
||||
@@ -286,11 +286,11 @@ fn pivot_into(new_root: str, stash_old_root: (str|void) = void) void = {
|
||||
match (stash_old_root) {
|
||||
case let old: str =>
|
||||
errors::ext::check("[namespace] mkdir <stash_old_root>", rt::mkdir(old, 0o755));
|
||||
errors::ext::check("[namespace] pivot_root . <stash_old_root>", rtext::pivot_root(".", old));
|
||||
errors::ext::check("[namespace] pivot_root . <stash_old_root>", rt::ext::pivot_root(".", old));
|
||||
case void =>
|
||||
errors::ext::check("[namespace] pivot_root . .", rtext::pivot_root(".", "."));
|
||||
errors::ext::check("[namespace] pivot_root . .", rt::ext::pivot_root(".", "."));
|
||||
// drop the old rootfs. weird idiom, but documented in `man 2 pivot_root`.
|
||||
errors::ext::check("[namespace] umount .", rt::umount2(".", rtext::umount_flag::MNT_DETACH));
|
||||
errors::ext::check("[namespace] umount .", rt::umount2(".", rt::ext::umount_flag::MNT_DETACH));
|
||||
};
|
||||
errors::ext::check("[namespace] cd /", os::chdir("/"));
|
||||
};
|
||||
|
Reference in New Issue
Block a user