nspawn: set ping group range for userns containers

A newly created network namespace may disallow ICMP echo sockets for
unprivileged users even when their GIDs are mapped into the container.

When creating both user and network namespaces, initialize
net.ipv4.ping_group_range using the mapped GID range capped at INT32_MAX.
This follows the system-wide default from sysctl.d/50-default.conf while
respecting the user namespace mapping and the kernel's accepted limit.
Leave externally supplied network namespaces untouched and treat write
failures as non-fatal warnings.

Add regression coverage for the default 64K mapped range using the tools
already available in the minimal container image.

Fixes #41603
This commit is contained in:
totoro
2026-08-26 11:45:35 +02:00
committed by Lennart Poettering
parent e1f9606096
commit 2fa149f2c4
2 changed files with 30 additions and 0 deletions
+10
View File
@@ -3264,6 +3264,16 @@ static int patch_sysctl(void) {
flags = effective_clone_ns_flags();
if (FLAGS_SET(flags, CLONE_NEWUSER|CLONE_NEWNET) && !arg_network_namespace_path) {
/* Follow the system-wide default from sysctl.d/50-default.conf, but clamp it to the
* groups mapped into the container's user namespace. */
r = sysctl_writef("net/ipv4/ping_group_range", "0 " GID_FMT,
MIN(arg_uid_range - 1, (gid_t) INT32_MAX));
if (r < 0)
log_warning_errno(r,
"Failed to set sysctl 'net.ipv4.ping_group_range', ignoring: %m");
}
STRV_FOREACH_PAIR(k, v, arg_sysctl) {
bool good = false;
+20
View File
@@ -1211,6 +1211,26 @@ matrix_run_one() {
return 0
}
testcase_ping_group_range() {
local range root
if [[ "$IS_USERNS_SUPPORTED" == "no" ]]; then
echo "Skipping user namespace test..."
return 0
fi
root="$(mktemp -d /var/lib/machines/TEST-13-NSPAWN.ping-group-range.XXX)"
create_dummy_container "$root"
trap 'rm -fr "$root"' RETURN ERR
range="$(systemd-nspawn --pipe --register=no \
--directory="$root" \
--private-network \
--private-users=pick \
cat /proc/sys/net/ipv4/ping_group_range)"
assert_eq "${range//[[:space:]]/ }" "0 65535"
}
testcase_api_vfs() {
local api_vfs_writable