diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c index 3b629b4a0359..9880756d9eff 100644 --- a/net/vmw_vsock/af_vsock.c +++ b/net/vmw_vsock/af_vsock.c @@ -95,8 +95,9 @@ * 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. * @@ -2844,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; }