From 5f5cda9706aae968c06ae6db343d8227da9a0dde Mon Sep 17 00:00:00 2001 From: Colin Date: Fri, 30 Aug 2024 13:17:24 +0000 Subject: [PATCH] refactor: bunpen: namespace: swallow /proc/self/*_map errors instead of aborting --- pkgs/additional/bunpen/errors/ext/check.ha | 4 +++- pkgs/additional/bunpen/restrict/namespace.ha | 24 ++++++++++++++------ 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/pkgs/additional/bunpen/errors/ext/check.ha b/pkgs/additional/bunpen/errors/ext/check.ha index 4cdeab84f..70a87d83a 100644 --- a/pkgs/additional/bunpen/errors/ext/check.ha +++ b/pkgs/additional/bunpen/errors/ext/check.ha @@ -1,4 +1,5 @@ // vim: set shiftwidth=2 : +use io; use fmt; use fs; use log; @@ -6,12 +7,13 @@ use os::exec; use path; use rt; -export type error = (fs::error | os::exec::error | path::error | rt::errno); +export type error = (io::error | fs::error | os::exec::error | path::error | rt::errno); // stringify an error. return value is statically allocated, no need to free. export fn maybe_strerror(what: (void | ...error)) (void | str) = { let errorbuf: [4096]u8 = [0...]; return match (what) { + case let e: io::error => yield io::strerror(e); case let e: fs::error => yield fs::strerror(e); case let e: os::exec::error => yield os::exec::strerror(e); case let e: path::error => yield path::strerror(e); diff --git a/pkgs/additional/bunpen/restrict/namespace.ha b/pkgs/additional/bunpen/restrict/namespace.ha index b133b127a..1e54f0312 100644 --- a/pkgs/additional/bunpen/restrict/namespace.ha +++ b/pkgs/additional/bunpen/restrict/namespace.ha @@ -45,7 +45,7 @@ export fn namespace_restrict(what: *resources) void = { // 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(uid, gid); + write_id_maps(uid, gid); if (!what.pid) { // fork and become: @@ -282,17 +282,27 @@ fn pivot_into(new_root: str, stash_old_root: (str|void) = void) void = { errors::ext::check("[namespace] cd /", os::chdir("/")); }; -fn write_uid_map(uid: unix::uid, gid: unix::gid) void = { - let uid_fd = rt::open("/proc/self/uid_map", rt::O_RDWR | rt::O_CLOEXEC, 0)!; +fn write_id_maps(uid: unix::uid, gid: unix::gid) void = { + errors::ext::swallow("[namespace] write /proc/self/uid_map", write_uid_map(uid)); + errors::ext::swallow("[namespace] write /proc/self/setgroups", write_setgroups()); + errors::ext::swallow("[namespace] write /proc/self/gid_map", write_gid_map(gid)); +}; + +fn write_uid_map(uid: unix::uid) (void | rt::errno | io::error) = { + let uid_fd = rt::open("/proc/self/uid_map", rt::O_RDWR | rt::O_CLOEXEC, 0)?; let uid_buf: [4096]u8 = [0...]; let uid_str = fmt::bsprintf(uid_buf, "{0} {0} 1\n", uid: uint); - io::write(uid_fd, strings::toutf8(uid_str))!; + io::write(uid_fd, strings::toutf8(uid_str))?; +}; - let setgroups_fd = rt::open("/proc/self/setgroups", rt::O_RDWR | rt::O_CLOEXEC, 0)!; - io::write(setgroups_fd, &['d': u8, 'e', 'n', 'y', '\n', 0])!; +fn write_setgroups() (void | rt::errno | io::error) = { + let setgroups_fd = rt::open("/proc/self/setgroups", rt::O_RDWR | rt::O_CLOEXEC, 0)?; + io::write(setgroups_fd, &['d': u8, 'e', 'n', 'y', '\n', 0])?; +}; +fn write_gid_map(gid: unix::gid) (void | rt::errno | io::error) = { let gid_fd = rt::open("/proc/self/gid_map", rt::O_RDWR | rt::O_CLOEXEC, 0)!; let gid_buf: [4096]u8 = [0...]; let gid_str = fmt::bsprintf(gid_buf, "{0} {0} 1\n", gid: uint); - io::write(gid_fd, strings::toutf8(gid_str))!; + io::write(gid_fd, strings::toutf8(gid_str))?; };