proc: make proc entries inherit ownership from parent
authorDmitry Torokhov <dmitry.torokhov@gmail.com>
Wed, 10 Aug 2016 21:36:01 +0000 (14:36 -0700)
committerDavid S. Miller <davem@davemloft.net>
Mon, 15 Aug 2016 04:07:20 +0000 (21:07 -0700)
There are certain parameters that belong to net namespace and that are
exported in /proc. They should be controllable by the container's owner,
but are currently owned by global root and thus not available.

Let's change proc code to inherit ownership of parent entry, and when
create per-ns "net" proc entry set it up as owned by container's owner.

Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
fs/proc/generic.c
fs/proc/proc_net.c

index c633476616e0fe7be920d9421f8eba627a4398b3..bca66d83a7659c1e79d7ae8f49a89959d2d4188c 100644 (file)
@@ -390,6 +390,8 @@ static struct proc_dir_entry *__proc_create(struct proc_dir_entry **parent,
        atomic_set(&ent->count, 1);
        spin_lock_init(&ent->pde_unload_lock);
        INIT_LIST_HEAD(&ent->pde_openers);
+       proc_set_user(ent, (*parent)->uid, (*parent)->gid);
+
 out:
        return ent;
 }
index c8bbc68cdb05923cec13752d7b575c76fdd7895c..7ae6b1da7cabcf44eebfe5e1566b29b8fb9d01d7 100644 (file)
@@ -21,6 +21,7 @@
 #include <linux/bitops.h>
 #include <linux/mount.h>
 #include <linux/nsproxy.h>
+#include <linux/uidgid.h>
 #include <net/net_namespace.h>
 #include <linux/seq_file.h>
 
@@ -185,6 +186,8 @@ const struct file_operations proc_net_operations = {
 static __net_init int proc_net_ns_init(struct net *net)
 {
        struct proc_dir_entry *netd, *net_statd;
+       kuid_t uid;
+       kgid_t gid;
        int err;
 
        err = -ENOMEM;
@@ -199,6 +202,16 @@ static __net_init int proc_net_ns_init(struct net *net)
        netd->parent = &proc_root;
        memcpy(netd->name, "net", 4);
 
+       uid = make_kuid(net->user_ns, 0);
+       if (!uid_valid(uid))
+               uid = netd->uid;
+
+       gid = make_kgid(net->user_ns, 0);
+       if (!gid_valid(gid))
+               gid = netd->gid;
+
+       proc_set_user(netd, uid, gid);
+
        err = -EEXIST;
        net_statd = proc_net_mkdir(net, "stat", netd);
        if (!net_statd)