bunpen: implement --bunpen-seal and show that nested sandboxing *does* work, currently

This commit is contained in:
2024-12-26 09:38:04 +00:00
parent 93e56a3757
commit 100dd34509
2 changed files with 48 additions and 21 deletions

View File

@@ -65,6 +65,10 @@ export fn usage() void = {
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(" a limited set of env vars are expanded within each path: see PARAMETERIZATION")!;
fmt::println(" --bunpen-seal")!;
fmt::println(" halt argument parsing")!;
fmt::println(" any remaining arguments are to be interpreted as arguments for the user program, not bunpen")!;
fmt::println(" note that remaining arguments *are* still eligible for path autodetection (see --bunpen-autodetect)")!;
fmt::println("")!;
fmt::println("net proxy settings (typical invocation specifies either ALL or NONE of these):")!;
fmt::println(" --bunpen-net-dev <iface>")!;
@@ -147,33 +151,39 @@ export fn parse_args(args: []str) (cli_opts | errors::invalid) = {
};
fn parse_args_into(parsed: *cli_opts, args: []str) (void | errors::invalid) = {
let parsing_bunpen = true;
for (let idx: size = 0; idx < len(args); idx += 1) {
let arg = args[idx];
let next: nullable *str = null;
if (idx + 1 < len(args)) {
next = &args[idx+1];
};
switch (arg) {
case "--bunpen-autodetect" => idx += 1; parsed.autodetect = autodetect_fromstr(expect_arg("--bunpen-autodetect", next)?)?;
case "--bunpen-cap" => idx += 1; parse_caparg(parsed, expect_arg("--bunpen-cap", next)?)?;
case "--bunpen-debug" => parsed.debug = 2;
case "--bunpen-debug=0" => parsed.debug = 0;
case "--bunpen-debug=1" => parsed.debug = 1;
case "--bunpen-debug=2" => parsed.debug = 2;
case "--bunpen-debug=3" => parsed.debug = 3;
case "--bunpen-debug=4" => parsed.debug = 4;
case "--bunpen-dns" => idx += 1; parsed.dns = expect_arg("--bunpen-dns", next)?;
case "--bunpen-drop-shell" => parsed.drop_shell = true;
case "--bunpen-env" => idx += 1; append(parsed.env, expect_arg("--bunpen-env", next)?);
case "--bunpen-help" => parsed.help = true;
case "--bunpen-keep-ipc" => parsed.keep_ipc = true;
case "--bunpen-keep-net" => parsed.keep_net = true;
case "--bunpen-keep-pid" => parsed.keep_pid = true;
case "--bunpen-net-dev" => idx += 1; parsed.net_dev = expect_arg("--bunpen-net-dev", next)?;
case "--bunpen-net-gateway" => idx += 1; parsed.net_gateway = expect_arg("--bunpen-net-gateway", next)?;
case "--bunpen-path" => idx += 1; append(parsed.paths, expect_arg("--bunpen-path", next)?);
case "--bunpen-try-keep-users" => parsed.try_keep_users = true;
case => append(parsed.cmd, arg);
if (parsing_bunpen) {
switch (arg) {
case "--bunpen-autodetect" => idx += 1; parsed.autodetect = autodetect_fromstr(expect_arg("--bunpen-autodetect", next)?)?;
case "--bunpen-cap" => idx += 1; parse_caparg(parsed, expect_arg("--bunpen-cap", next)?)?;
case "--bunpen-debug" => parsed.debug = 2;
case "--bunpen-debug=0" => parsed.debug = 0;
case "--bunpen-debug=1" => parsed.debug = 1;
case "--bunpen-debug=2" => parsed.debug = 2;
case "--bunpen-debug=3" => parsed.debug = 3;
case "--bunpen-debug=4" => parsed.debug = 4;
case "--bunpen-dns" => idx += 1; parsed.dns = expect_arg("--bunpen-dns", next)?;
case "--bunpen-drop-shell" => parsed.drop_shell = true;
case "--bunpen-env" => idx += 1; append(parsed.env, expect_arg("--bunpen-env", next)?);
case "--bunpen-help" => parsed.help = true;
case "--bunpen-keep-ipc" => parsed.keep_ipc = true;
case "--bunpen-keep-net" => parsed.keep_net = true;
case "--bunpen-keep-pid" => parsed.keep_pid = true;
case "--bunpen-net-dev" => idx += 1; parsed.net_dev = expect_arg("--bunpen-net-dev", next)?;
case "--bunpen-net-gateway" => idx += 1; parsed.net_gateway = expect_arg("--bunpen-net-gateway", next)?;
case "--bunpen-path" => idx += 1; append(parsed.paths, expect_arg("--bunpen-path", next)?);
case "--bunpen-seal" => parsing_bunpen = false; // remaining arguments are not to be interpreted by us
case "--bunpen-try-keep-users" => parsed.try_keep_users = true;
case => append(parsed.cmd, arg);
};
} else {
append(parsed.cmd, arg);
};
};
};

View File

@@ -8,6 +8,7 @@ set -eu
SELF=$(realpath $0)
# we can't rely on /usr/bin/env existing in the nix build environment
bunpen=$(which bunpen)
env=$(which env)
test=$(which test)
@@ -38,6 +39,10 @@ test_01_invoke_04_errors_if_not_in_sandbox() {
bunpen true && return 1 || true
}
test_01_invoke_05_nested() {
bunpen --bunpen-path / --bunpen-seal bunpen --bunpen-path / true
}
test_02_env_arg_01_disable() {
BUNPEN_DISABLE=1 bunpen true
}
@@ -163,6 +168,18 @@ test_06_keep_11_pid() {
! bunpen --bunpen-path /nix/store --bunpen-path /proc "$test" -e /proc/$me
}
test_06_keep_12_pid_nested() {
set -x
bunpen --bunpen-path /nix/store --bunpen-path "$bunpen" --bunpen-seal \
"$bunpen" --bunpen-path /nix/store "$test" -e /proc/self
bunpen --bunpen-path /nix/store --bunpen-path "$bunpen" --bunpen-path /proc --bunpen-keep-pid --bunpen-seal \
"$bunpen" --bunpen-path /nix/store "$test" -e /proc/self
bunpen --bunpen-path /nix/store --bunpen-path "$bunpen" --bunpen-seal \
"$bunpen" --bunpen-path /nix/store --bunpen-path "$bunpen" --bunpen-seal \
"$bunpen" --bunpen-path /nix/store "$test" -e /proc/self
}
test_07_env_01_keep() {
ORIG_ENV=orig bunpen --bunpen-path / bash -c '[[ "$ORIG_ENV" = orig && -z "$NOT_ENV" ]]'
}