Skip the net-namespace-isolation test when policy disables it
Found by running the full suite as root with every unshare-* flag forced off via -c/--config-file: this test only ever checked kernel support for --unshare-net, never the config's own policy, so disabling it via global.unshare-net correctly makes bwrap skip requesting the namespace -- production code working exactly as configured, not a bug -- while the test still asserted isolation and failed. Generalized the existing pid-only two-gate check into namespace_type_would_isolate(type), covering any of bwrap.cpp's own namespace_probes names, and used it here instead of a kernel-support-only check.
This commit is contained in:
@@ -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,
|
// 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-<type> for a
|
||||||
// container it creates -- both the config's own policy *and* live kernel
|
// 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
|
// support (detect_bwrap_unshare_args(), bwrap.h) have to allow it, the same
|
||||||
// two-gate check build_bwrap_args() itself applies.
|
// two-gate check build_bwrap_args() itself applies. `type` is one of
|
||||||
bool pid_namespace_would_isolate() {
|
// "user"/"ipc"/"pid"/"net"/"uts"/"cgroup", matching bwrap.cpp's own
|
||||||
if (!g_test_app_config.unshare_pid.value_or(true)) {
|
// 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;
|
return false;
|
||||||
}
|
}
|
||||||
auto supported = detect_bwrap_unshare_args();
|
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
|
// 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) {
|
if (!image) {
|
||||||
SKIP("no busybox fixture (images/busybox.tar) -- see tests/setup-tests.py");
|
SKIP("no busybox fixture (images/busybox.tar) -- see tests/setup-tests.py");
|
||||||
}
|
}
|
||||||
auto supported = detect_bwrap_unshare_args();
|
// Covers both "the kernel doesn't support net namespaces" (the original
|
||||||
if (std::find(supported.begin(), supported.end(), "--unshare-net") == supported.end()) {
|
// check here) and "the config's own policy disables it" (found by
|
||||||
SKIP("this kernel doesn't support net namespaces");
|
// 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;
|
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
|
// 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
|
// deliberately-crippled config (e.g. via -c/--config-file, g_test_app_config
|
||||||
// above) doesn't produce a misleading failure here.
|
// 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 "
|
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");
|
"current config/kernel -- no mechanism exists to reap a reparented straggler here");
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user