Commit 36e83863 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'vsock-fix-child-netns-mode-initialization-and-restriction'

Stefano Garzarella says:

====================
vsock: fix child netns mode initialization and restriction

This series fixes two issues in the vsock network namespace support
recently introduced by commit eafb64f4 ("vsock: add netns to vsock
core").

Patch 1 fixes `child_ns_mode` being always hardcoded to "global" for new
namespaces, breaking propagation of the "local" mode through nested
namespaces.

Patch 2 prevents a "local" namespace from switching `child_ns_mode` to
"global", which would allow nested namespaces to escape vsock isolation
and access global CIDs.
====================

Link: https://patch.msgid.link/20260212205916.97533-1-sgarzare@redhat.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents a49d2a2c 6a997f38
Loading
Loading
Loading
Loading
+15 −5
Original line number Diff line number Diff line
@@ -91,11 +91,13 @@
 *   - /proc/sys/net/vsock/ns_mode (read-only) reports the current namespace's
 *     mode, which is set at namespace creation and immutable thereafter.
 *   - /proc/sys/net/vsock/child_ns_mode (writable) controls what mode future
 *     child namespaces will inherit when created. The default is "global".
 *     child namespaces will inherit when created. The initial value matches
 *     the namespace's own ns_mode.
 *
 *   Changing child_ns_mode only affects newly created namespaces, not the
 *   current namespace or existing children. At namespace creation, ns_mode
 *   is inherited from the parent's child_ns_mode.
 *   current namespace or existing children. A "local" namespace cannot set
 *   child_ns_mode to "global". At namespace creation, ns_mode is inherited
 *   from the parent's child_ns_mode.
 *
 *   The init_net mode is "global" and cannot be modified.
 *
@@ -2843,8 +2845,16 @@ static int vsock_net_child_mode_string(const struct ctl_table *table, int write,
	if (ret)
		return ret;

	if (write)
	if (write) {
		/* Prevent a "local" namespace from escalating to "global",
		 * which would give nested namespaces access to global CIDs.
		 */
		if (vsock_net_mode(net) == VSOCK_NET_MODE_LOCAL &&
		    new_mode == VSOCK_NET_MODE_GLOBAL)
			return -EPERM;

		vsock_net_set_child_mode(net, new_mode);
	}

	return 0;
}
@@ -2912,7 +2922,7 @@ static void vsock_net_init(struct net *net)
	else
		net->vsock.mode = vsock_net_child_mode(current->nsproxy->net_ns);

	net->vsock.child_ns_mode = VSOCK_NET_MODE_GLOBAL;
	net->vsock.child_ns_mode = net->vsock.mode;
}

static __net_init int vsock_sysctl_init_net(struct net *net)