bunpen: lay the plumbing for future pid isolation

This commit is contained in:
2024-08-29 14:13:38 +00:00
parent a2fa3727cc
commit 452ee68926
5 changed files with 22 additions and 2 deletions

View File

@@ -15,6 +15,7 @@ export type cli_opts = struct {
help: bool,
home_paths: []str,
keep_net: bool,
keep_pid: bool,
paths: []str,
run_paths: []str,
};
@@ -28,7 +29,7 @@ export type autodetect = enum {
};
export fn usage() void = {
fmt::println("bunpen: run a program within an environment where access to external resources (files, net) is restricted (i.e. sandbox)")!;
fmt::println("bunpen: run a program within an environment where access to external resources (files, net, certain IPC, ...) is restricted (i.e. sandbox)")!;
fmt::println("USAGE: bunpen [sandbox-arg ...] program [sandbox-arg|program-arg ...] [--] [program-arg ...]")!;
fmt::println("")!;
fmt::println("sandbox args and program args may be intermixed, but the first `--` anywhere signals the end of the sandbox args and the start of program args")!;
@@ -45,6 +46,8 @@ export fn usage() void = {
fmt::println(" add files which appear later as CLI arguments into the sandbox")!;
fmt::println(" --bunpen-keep-net")!;
fmt::println(" allow unrestricted access to the network")!;
fmt::println(" --bunpen-keep-pid")!;
fmt::println(" allow this process to see other processes running on the machine")!;
fmt::println(" --bunpen-path <path>")!;
fmt::println(" allow access to the host <path> within the sandbox")!;
fmt::println(" path is interpreted relative to the working directory if not absolute")!;
@@ -101,6 +104,7 @@ export fn parse_args(args: []str) (cli_opts | error) = {
case "--bunpen-help" => parsed.help = true;
case "--bunpen-home-path" => idx += 1; append(parsed.home_paths, expect_arg("--bunpen-home-path", next)?);
case "--bunpen-keep-net" => parsed.keep_net = true;
case "--bunpen-keep-pid" => parsed.keep_pid = true;
case "--bunpen-path" => idx += 1; append(parsed.paths, expect_arg("--bunpen-path", next)?);
case "--bunpen-run-path" => idx += 1; append(parsed.run_paths, expect_arg("--bunpen-run-path", next)?);
case => append(parsed.cmd, arg);

View File

@@ -20,6 +20,7 @@ export type cli_request = struct {
// if the user requested `--bunpen-drop-shell`, this will be their shell (e.g. /bin/sh).
exec_bin: str,
keep_net: bool,
keep_pid: bool,
// absolute paths to the resources which should be made available to the
// sandbox. these may not all actually exist, and could contain entries like
// `/proc/self`; how to interpret such paths is left to the sandbox impl.
@@ -56,6 +57,9 @@ export fn ingest_cli_opts(opts: cli_opts) (cli_request | help) = {
//---- ingest `keep_net` ----//
req.keep_net = opts.keep_net;
//---- ingest `keep_pid` ----//
req.keep_pid = opts.keep_pid;
//---- ingest `paths` ----//
ingest_paths(&req.paths, opts.paths, os::getcwd(), true);

View File

@@ -48,6 +48,7 @@ export fn main() void = {
let what = restrict::resources {
paths = req.paths,
net = req.keep_net,
pid = req.keep_pid,
};
rtext::no_new_privs()!;

View File

@@ -22,13 +22,21 @@ export fn namespace_restrict(what: *resources) void = {
rtext::CLONE_NEWIPC |
rtext::CLONE_NEWNET |
rtext::CLONE_NEWNS |
rtext::CLONE_NEWPID |
rtext::CLONE_NEWUSER |
rtext::CLONE_NEWUTS
;
if (what.net) {
log::println("[namespace] permit net");
log::println("[namespace] keeping net namespace");
what_to_unshare &= ~rtext::CLONE_NEWNET;
};
if (what.pid) {
log::println("[namespace] keeping pid namespace");
what_to_unshare &= ~rtext::CLONE_NEWPID;
} else {
log::println("TODO: namespacing without --bunpen-keep-pid is unsupported");
what_to_unshare &= ~rtext::CLONE_NEWPID;
};
log::printfln("[namespace] unshare {}", what_to_unshare);
rtext::unshare(what_to_unshare)!;

View File

@@ -8,4 +8,7 @@ export type resources = struct {
// true to allow unrestricted net access.
// false to maximally disable net access.
net: bool,
// true to allow operations on other processes (e.g. viewing their cmdline,
// killing them, etc).
pid: bool,
};