refactor: bunpen: implement and use check_u64 to cover most remaining uses of !

This commit is contained in:
2024-08-30 13:41:11 +00:00
parent 6f71d2f8db
commit cfb5a7651b
3 changed files with 53 additions and 26 deletions

View File

@@ -3,6 +3,7 @@ use io;
use fmt; use fmt;
use fs; use fs;
use log; use log;
use os;
use os::exec; use os::exec;
use path; use path;
use rt; use rt;
@@ -31,31 +32,45 @@ export fn strerror(what: error) str = {
}; };
}; };
export fn check(context: str, what: (void | ...error), fmt_args: fmt::field...) void = { fn nonfatal(context: str, e: error, fmt_args: fmt::field...) void = {
let context_buf: [4096]u8 = [0...]; let context_buf: [4096]u8 = [0...];
match (maybe_strerror(what)) { log::println(
// N.B.: use `fatal(...)` over `fatalf("{}: {}")` so that my treelogger fmt::bsprintf(context_buf[..], context, fmt_args...),
// can extract the context. ":",
case let errstr: str => log::fatal( strerror(e),
fmt::bsprintf(context_buf[..], context, fmt_args...), );
":", };
errstr,
); fn fatal(context: str, e: error, fmt_args: fmt::field...) never = {
case void => void; nonfatal(context, e, fmt_args...);
os::exit(255);
};
export fn check(context: str, what: (void | ...error), fmt_args: fmt::field...) void = {
return match (what) {
case void => yield void;
case let e: error => fatal(context, e, fmt_args...);
};
};
export fn check_u64(context: str, what: (u64 | ...error), fmt_args: fmt::field...) u64 = {
return match (what) {
case let v: u64 => yield v;
case let e: error => fatal(context, e, fmt_args...);
};
};
export fn check_int(context: str, what: (int | ...error), fmt_args: fmt::field...) int = {
return match (what) {
case let v: int => yield v;
case let e: error => fatal(context, e, fmt_args...);
}; };
}; };
export fn swallow(context: str, what: (void | ...error), fmt_args: fmt::field...) void = { export fn swallow(context: str, what: (void | ...error), fmt_args: fmt::field...) void = {
let context_buf: [4096]u8 = [0...]; return match (what) {
match (maybe_strerror(what)) { case void => yield void;
// N.B.: use `println(...)` over `printfln("{}: {}")` so that my treelogger case let e: error => nonfatal(context, e, fmt_args...);
// can extract the context.
case let errstr: str => log::println(
fmt::bsprintf(context_buf[..], context, fmt_args...),
":",
errstr,
);
case void => void;
}; };
}; };

View File

@@ -58,7 +58,10 @@ fn allow_path(ruleset_fd: u64, path_str: str) (void | fs::error | rt::errno) = {
}; };
export fn landlock_restrict(what: *resources) void = { export fn landlock_restrict(what: *resources) void = {
let abi = rt::ext::landlock_create_ruleset(null, rt::ext::landlock_create_ruleset_flag::VERSION)!; let abi = errors::ext::check_u64(
"query landlock kernel ABI version",
rt::ext::landlock_create_ruleset(null, rt::ext::landlock_create_ruleset_flag::VERSION),
);
log::printfln("[landlock] found version {}", abi); log::printfln("[landlock] found version {}", abi);
// determine the access modes we can ask this kernel to restrict on: // determine the access modes we can ask this kernel to restrict on:
@@ -85,7 +88,10 @@ export fn landlock_restrict(what: *resources) void = {
ruleset_attr.handled_access_net = 0; ruleset_attr.handled_access_net = 0;
}; // XXX: `what.net` only affects TCP. UDP, and ICMP remain possible always }; // XXX: `what.net` only affects TCP. UDP, and ICMP remain possible always
let ruleset_fd = rt::ext::landlock_create_ruleset(&ruleset_attr)!; let ruleset_fd = errors::ext::check_u64(
"landlock_create_ruleset",
rt::ext::landlock_create_ruleset(&ruleset_attr),
);
for (let pathbuf .. what.paths) { for (let pathbuf .. what.paths) {
let pathstr = path::string(&pathbuf); let pathstr = path::string(&pathbuf);
@@ -93,7 +99,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)); errors::ext::swallow("[landlock/path] omitting from sandbox: failed to add path", allow_path(ruleset_fd, pathstr));
}; };
rt::ext::landlock_restrict_self(ruleset_fd)!; errors::ext::check_u64("landlock_restrict_self", rt::ext::landlock_restrict_self(ruleset_fd));
log::println("landlock restrictions activated"); log::println("landlock restrictions activated");
}; };

View File

@@ -139,10 +139,16 @@ fn isolate_paths(paths: []path::buffer) void = {
// bind all the user-requested paths from `old/$p` into `new/$p`. // 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 // use the `dirfd` abstraction so that paths meant for `old` can't crawl out
// of that virtual fs. // of that virtual fs.
let old_fd = rt::open("old", rt::O_RDONLY | rt::O_CLOEXEC, rt::RESOLVE_NO_SYMLINKS: uint)!; let old_fd = errors::ext::check_int(
"namespace setup: open /old",
rt::open("old", rt::O_RDONLY | rt::O_CLOEXEC, rt::RESOLVE_NO_SYMLINKS: uint)
);
let old_fs = os::dirfdopen(old_fd); let old_fs = os::dirfdopen(old_fd);
defer(free(old_fs)); defer(free(old_fs));
let new_fd = rt::open("new", rt::O_RDONLY | rt::O_CLOEXEC, rt::RESOLVE_NO_SYMLINKS: uint)!; let new_fd = errors::ext::check_int(
"namespace setup: open /new",
rt::open("new", rt::O_RDONLY | rt::O_CLOEXEC, rt::RESOLVE_NO_SYMLINKS: uint),
);
let new_fs = os::dirfdopen(new_fd); let new_fs = os::dirfdopen(new_fd);
defer(free(new_fs)); defer(free(new_fs));
@@ -187,7 +193,7 @@ fn bind_leaf(old_fs: *fs::fs, new_fs: *fs::fs, user_path: *path::buffer) (void |
log::printfln("[namespace] permit path: {}", path_str); log::printfln("[namespace] permit path: {}", path_str);
let it = path::iter(user_path); let it = path::iter(user_path);
let cur_path = path::init()!; let cur_path = path::init()?;
let cur_strpath = ""; let cur_strpath = "";
for (let comp => path::nextiter(&it)) { for (let comp => path::nextiter(&it)) {
if (comp == "..") { if (comp == "..") {