bunpen: lay the plumbing for future pid isolation
This commit is contained in:
@@ -15,6 +15,7 @@ export type cli_opts = struct {
|
|||||||
help: bool,
|
help: bool,
|
||||||
home_paths: []str,
|
home_paths: []str,
|
||||||
keep_net: bool,
|
keep_net: bool,
|
||||||
|
keep_pid: bool,
|
||||||
paths: []str,
|
paths: []str,
|
||||||
run_paths: []str,
|
run_paths: []str,
|
||||||
};
|
};
|
||||||
@@ -28,7 +29,7 @@ export type autodetect = enum {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export fn usage() void = {
|
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("USAGE: bunpen [sandbox-arg ...] program [sandbox-arg|program-arg ...] [--] [program-arg ...]")!;
|
||||||
fmt::println("")!;
|
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")!;
|
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(" add files which appear later as CLI arguments into the sandbox")!;
|
||||||
fmt::println(" --bunpen-keep-net")!;
|
fmt::println(" --bunpen-keep-net")!;
|
||||||
fmt::println(" allow unrestricted access to the network")!;
|
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(" --bunpen-path <path>")!;
|
||||||
fmt::println(" allow access to the host <path> within the sandbox")!;
|
fmt::println(" allow access to the host <path> within the sandbox")!;
|
||||||
fmt::println(" path is interpreted relative to the working directory if not absolute")!;
|
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-help" => parsed.help = true;
|
||||||
case "--bunpen-home-path" => idx += 1; append(parsed.home_paths, expect_arg("--bunpen-home-path", next)?);
|
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-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-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 "--bunpen-run-path" => idx += 1; append(parsed.run_paths, expect_arg("--bunpen-run-path", next)?);
|
||||||
case => append(parsed.cmd, arg);
|
case => append(parsed.cmd, arg);
|
||||||
|
@@ -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).
|
// if the user requested `--bunpen-drop-shell`, this will be their shell (e.g. /bin/sh).
|
||||||
exec_bin: str,
|
exec_bin: str,
|
||||||
keep_net: bool,
|
keep_net: bool,
|
||||||
|
keep_pid: bool,
|
||||||
// absolute paths to the resources which should be made available to the
|
// absolute paths to the resources which should be made available to the
|
||||||
// sandbox. these may not all actually exist, and could contain entries like
|
// 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.
|
// `/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` ----//
|
//---- ingest `keep_net` ----//
|
||||||
req.keep_net = opts.keep_net;
|
req.keep_net = opts.keep_net;
|
||||||
|
|
||||||
|
//---- ingest `keep_pid` ----//
|
||||||
|
req.keep_pid = opts.keep_pid;
|
||||||
|
|
||||||
//---- ingest `paths` ----//
|
//---- ingest `paths` ----//
|
||||||
ingest_paths(&req.paths, opts.paths, os::getcwd(), true);
|
ingest_paths(&req.paths, opts.paths, os::getcwd(), true);
|
||||||
|
|
||||||
|
@@ -48,6 +48,7 @@ export fn main() void = {
|
|||||||
let what = restrict::resources {
|
let what = restrict::resources {
|
||||||
paths = req.paths,
|
paths = req.paths,
|
||||||
net = req.keep_net,
|
net = req.keep_net,
|
||||||
|
pid = req.keep_pid,
|
||||||
};
|
};
|
||||||
|
|
||||||
rtext::no_new_privs()!;
|
rtext::no_new_privs()!;
|
||||||
|
@@ -22,13 +22,21 @@ export fn namespace_restrict(what: *resources) void = {
|
|||||||
rtext::CLONE_NEWIPC |
|
rtext::CLONE_NEWIPC |
|
||||||
rtext::CLONE_NEWNET |
|
rtext::CLONE_NEWNET |
|
||||||
rtext::CLONE_NEWNS |
|
rtext::CLONE_NEWNS |
|
||||||
|
rtext::CLONE_NEWPID |
|
||||||
rtext::CLONE_NEWUSER |
|
rtext::CLONE_NEWUSER |
|
||||||
rtext::CLONE_NEWUTS
|
rtext::CLONE_NEWUTS
|
||||||
;
|
;
|
||||||
if (what.net) {
|
if (what.net) {
|
||||||
log::println("[namespace] permit net");
|
log::println("[namespace] keeping net namespace");
|
||||||
what_to_unshare &= ~rtext::CLONE_NEWNET;
|
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);
|
log::printfln("[namespace] unshare {}", what_to_unshare);
|
||||||
rtext::unshare(what_to_unshare)!;
|
rtext::unshare(what_to_unshare)!;
|
||||||
|
@@ -8,4 +8,7 @@ export type resources = struct {
|
|||||||
// true to allow unrestricted net access.
|
// true to allow unrestricted net access.
|
||||||
// false to maximally disable net access.
|
// false to maximally disable net access.
|
||||||
net: bool,
|
net: bool,
|
||||||
|
// true to allow operations on other processes (e.g. viewing their cmdline,
|
||||||
|
// killing them, etc).
|
||||||
|
pid: bool,
|
||||||
};
|
};
|
||||||
|
Reference in New Issue
Block a user