summaryrefslogtreecommitdiff
path: root/net/vmw_vsock
diff options
context:
space:
mode:
Diffstat (limited to 'net/vmw_vsock')
-rw-r--r--net/vmw_vsock/af_vsock.c19
1 files changed, 12 insertions, 7 deletions
diff --git a/net/vmw_vsock/af_vsock.c b/net/vmw_vsock/af_vsock.c
index 9880756d9eff..2f7d94d682cb 100644
--- a/net/vmw_vsock/af_vsock.c
+++ b/net/vmw_vsock/af_vsock.c
@@ -90,16 +90,20 @@
*
* - /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
+ * - /proc/sys/net/vsock/child_ns_mode (write-once) controls what mode future
* 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. A "local" namespace cannot set
- * child_ns_mode to "global". At namespace creation, ns_mode is inherited
- * from the parent's child_ns_mode.
+ * child_ns_mode to "global". child_ns_mode is write-once, so that it may be
+ * configured and locked down by a namespace manager. Writing a different
+ * value after the first write returns -EBUSY. At namespace creation, ns_mode
+ * is inherited from the parent's child_ns_mode.
*
- * The init_net mode is "global" and cannot be modified.
+ * The init_net mode is "global" and cannot be modified. The init_net
+ * child_ns_mode is also write-once, so an init process (e.g. systemd) can
+ * set it to "local" to ensure all new namespaces inherit local mode.
*
* The modes affect the allocation and accessibility of CIDs as follows:
*
@@ -2825,7 +2829,7 @@ static int vsock_net_mode_string(const struct ctl_table *table, int write,
if (write)
return -EPERM;
- net = current->nsproxy->net_ns;
+ net = container_of(table->data, struct net, vsock.mode);
return __vsock_net_mode_string(table, write, buffer, lenp, ppos,
vsock_net_mode(net), NULL);
@@ -2838,7 +2842,7 @@ static int vsock_net_child_mode_string(const struct ctl_table *table, int write,
struct net *net;
int ret;
- net = current->nsproxy->net_ns;
+ net = container_of(table->data, struct net, vsock.child_ns_mode);
ret = __vsock_net_mode_string(table, write, buffer, lenp, ppos,
vsock_net_child_mode(net), &new_mode);
@@ -2853,7 +2857,8 @@ static int vsock_net_child_mode_string(const struct ctl_table *table, int write,
new_mode == VSOCK_NET_MODE_GLOBAL)
return -EPERM;
- vsock_net_set_child_mode(net, new_mode);
+ if (!vsock_net_set_child_mode(net, new_mode))
+ return -EBUSY;
}
return 0;