diff --git a/tests/integration/test_rootless_run.cpp b/tests/integration/test_rootless_run.cpp index bb1c8e3..decb9df 100644 --- a/tests/integration/test_rootless_run.cpp +++ b/tests/integration/test_rootless_run.cpp @@ -220,16 +220,38 @@ bool sleep_process_gone_within(const std::string& arg, int timeout_ms) { } // Whether the current -t run's effective config (g_test_app_config, -// fixtures.h) would actually get bwrap to request --unshare-pid for a +// fixtures.h) would actually get bwrap to request --unshare- for a // container it creates -- both the config's own policy *and* live kernel // support (detect_bwrap_unshare_args(), bwrap.h) have to allow it, the same -// two-gate check build_bwrap_args() itself applies. -bool pid_namespace_would_isolate() { - if (!g_test_app_config.unshare_pid.value_or(true)) { +// two-gate check build_bwrap_args() itself applies. `type` is one of +// "user"/"ipc"/"pid"/"net"/"uts"/"cgroup", matching bwrap.cpp's own +// namespace_probes names. Root never actually requests --unshare-user +// (bwrap.cpp) regardless of policy, so "user" always reports false here -- +// callers that care about that distinction (this file's own "every +// kernel-supported namespace type" test) already exclude it up front rather +// than relying on this to explain why. +bool namespace_type_would_isolate(const std::string& type) { + bool policy_enabled; + if (type == "user") { + policy_enabled = g_test_app_config.unshare_user.value_or(true); + } else if (type == "ipc") { + policy_enabled = g_test_app_config.unshare_ipc.value_or(true); + } else if (type == "pid") { + policy_enabled = g_test_app_config.unshare_pid.value_or(true); + } else if (type == "net") { + policy_enabled = g_test_app_config.unshare_net.value_or(true); + } else if (type == "uts") { + policy_enabled = g_test_app_config.unshare_uts.value_or(true); + } else if (type == "cgroup") { + policy_enabled = g_test_app_config.unshare_cgroup.value_or(true); + } else { + policy_enabled = true; // unreachable given the fixed set of types above + } + if (!policy_enabled) { return false; } auto supported = detect_bwrap_unshare_args(); - return std::find(supported.begin(), supported.end(), "--unshare-pid") != supported.end(); + return std::find(supported.begin(), supported.end(), "--unshare-" + type) != supported.end(); } // Whether run_bwrap()'s own session cgroup (session_cgroup.h) would actually @@ -263,9 +285,16 @@ TEST_CASE("rootless -r/--run: network namespace is genuinely isolated, loopback if (!image) { SKIP("no busybox fixture (images/busybox.tar) -- see tests/setup-tests.py"); } - auto supported = detect_bwrap_unshare_args(); - if (std::find(supported.begin(), supported.end(), "--unshare-net") == supported.end()) { - SKIP("this kernel doesn't support net namespaces"); + // Covers both "the kernel doesn't support net namespaces" (the original + // check here) and "the config's own policy disables it" (found by + // running the full suite as root with every unshare-* flag forced off + // via -c/--config-file, per the user's own explicit request) -- with + // unshare-net disabled, bwrap genuinely never requests --unshare-net, so + // the sandbox correctly shares the host's own net namespace; that's the + // production code doing exactly what it was told, not a bug, so this + // test SKIPs rather than reports a false failure. + if (!namespace_type_would_isolate("net")) { + SKIP("net namespace isolation is not available under the current config/kernel"); } ScratchXdgDirs scratch; @@ -363,7 +392,7 @@ TEST_CASE("rootless -r/--run: a nohup-backgrounded process does not survive the // regression this test should be flagging. Skip rather than fail so a // deliberately-crippled config (e.g. via -c/--config-file, g_test_app_config // above) doesn't produce a misleading failure here. - if (!pid_namespace_would_isolate() && !session_cgroup_would_work()) { + if (!namespace_type_would_isolate("pid") && !session_cgroup_would_work()) { SKIP("neither a pid namespace nor a working session cgroup is available under the " "current config/kernel -- no mechanism exists to reap a reparented straggler here"); }