diff --git a/pkgs/additional/bunpen/errors/ext/check.ha b/pkgs/additional/bunpen/errors/ext/check.ha index 70a87d83a..4c1291822 100644 --- a/pkgs/additional/bunpen/errors/ext/check.ha +++ b/pkgs/additional/bunpen/errors/ext/check.ha @@ -3,6 +3,7 @@ use io; use fmt; use fs; use log; +use os; use os::exec; use path; 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...]; - match (maybe_strerror(what)) { - // N.B.: use `fatal(...)` over `fatalf("{}: {}")` so that my treelogger - // can extract the context. - case let errstr: str => log::fatal( - fmt::bsprintf(context_buf[..], context, fmt_args...), - ":", - errstr, - ); - case void => void; + log::println( + fmt::bsprintf(context_buf[..], context, fmt_args...), + ":", + strerror(e), + ); +}; + +fn fatal(context: str, e: error, fmt_args: fmt::field...) never = { + 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 = { - let context_buf: [4096]u8 = [0...]; - match (maybe_strerror(what)) { - // N.B.: use `println(...)` over `printfln("{}: {}")` so that my treelogger - // can extract the context. - case let errstr: str => log::println( - fmt::bsprintf(context_buf[..], context, fmt_args...), - ":", - errstr, - ); - case void => void; + return match (what) { + case void => yield void; + case let e: error => nonfatal(context, e, fmt_args...); }; }; diff --git a/pkgs/additional/bunpen/restrict/landlock.ha b/pkgs/additional/bunpen/restrict/landlock.ha index 4c17b07f6..c2709d070 100644 --- a/pkgs/additional/bunpen/restrict/landlock.ha +++ b/pkgs/additional/bunpen/restrict/landlock.ha @@ -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 = { - 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); // 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; }; // 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) { 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)); }; - 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"); }; diff --git a/pkgs/additional/bunpen/restrict/namespace.ha b/pkgs/additional/bunpen/restrict/namespace.ha index 380af8aa0..e583e7d5f 100644 --- a/pkgs/additional/bunpen/restrict/namespace.ha +++ b/pkgs/additional/bunpen/restrict/namespace.ha @@ -139,10 +139,16 @@ fn isolate_paths(paths: []path::buffer) void = { // 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 // 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); 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); 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); let it = path::iter(user_path); - let cur_path = path::init()!; + let cur_path = path::init()?; let cur_strpath = ""; for (let comp => path::nextiter(&it)) { if (comp == "..") {