sysctl: Pass useful parameters to sysctl permissions
authorEric W. Biederman <ebiederm@xmission.com>
Fri, 16 Nov 2012 03:02:58 +0000 (03:02 +0000)
committerDavid S. Miller <davem@davemloft.net>
Mon, 19 Nov 2012 01:30:55 +0000 (20:30 -0500)
- Current is implicitly avaiable so passing current->nsproxy isn't useful.
- The ctl_table_header is needed to find how the sysctl table is connected
  to the rest of sysctl.
- ctl_table_root is avaiable in the ctl_table_header so no need to it.

With these changes it becomes possible to write a version of
net_sysctl_permission that takes into account the network namespace of
the sysctl table, an important feature in extending the user namespace.

Acked-by: Serge Hallyn <serge.hallyn@canonical.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
fs/proc/proc_sysctl.c
include/linux/sysctl.h
net/sysctl_net.c

index a781bdf0669464ced3e213faad5ed6ab3a37a06b..701580ddfcc3c20a4476fe88a9e736b54ca7b858 100644 (file)
@@ -378,12 +378,13 @@ static int test_perm(int mode, int op)
        return -EACCES;
 }
 
-static int sysctl_perm(struct ctl_table_root *root, struct ctl_table *table, int op)
+static int sysctl_perm(struct ctl_table_header *head, struct ctl_table *table, int op)
 {
+       struct ctl_table_root *root = head->root;
        int mode;
 
        if (root->permissions)
-               mode = root->permissions(root, current->nsproxy, table);
+               mode = root->permissions(head, table);
        else
                mode = table->mode;
 
@@ -491,7 +492,7 @@ static ssize_t proc_sys_call_handler(struct file *filp, void __user *buf,
         * and won't be until we finish.
         */
        error = -EPERM;
-       if (sysctl_perm(head->root, table, write ? MAY_WRITE : MAY_READ))
+       if (sysctl_perm(head, table, write ? MAY_WRITE : MAY_READ))
                goto out;
 
        /* if that can happen at all, it should be -EINVAL, not -EISDIR */
@@ -717,7 +718,7 @@ static int proc_sys_permission(struct inode *inode, int mask)
        if (!table) /* global root - r-xr-xr-x */
                error = mask & MAY_WRITE ? -EACCES : 0;
        else /* Use the permissions on the sysctl table entry */
-               error = sysctl_perm(head->root, table, mask & ~MAY_NOT_BLOCK);
+               error = sysctl_perm(head, table, mask & ~MAY_NOT_BLOCK);
 
        sysctl_head_finish(head);
        return error;
index cd844a6a8d5f9f766503f91d229694918cbe14fc..14a8ff2de11e54907ff63d20ee23c7d4c29896fa 100644 (file)
@@ -158,8 +158,7 @@ struct ctl_table_root {
        struct ctl_table_set default_set;
        struct ctl_table_set *(*lookup)(struct ctl_table_root *root,
                                           struct nsproxy *namespaces);
-       int (*permissions)(struct ctl_table_root *root,
-                       struct nsproxy *namespaces, struct ctl_table *table);
+       int (*permissions)(struct ctl_table_header *head, struct ctl_table *table);
 };
 
 /* struct ctl_path describes where in the hierarchy a table is added */
index e3a6e37cd1c536cc93d5caa850219e4104bb646b..e98f3932bdfb177fc76070f5f81eab02f30f3781 100644 (file)
@@ -38,8 +38,7 @@ static int is_seen(struct ctl_table_set *set)
 }
 
 /* Return standard mode bits for table entry. */
-static int net_ctl_permissions(struct ctl_table_root *root,
-                              struct nsproxy *nsproxy,
+static int net_ctl_permissions(struct ctl_table_header *head,
                               struct ctl_table *table)
 {
        /* Allow network administrator to have same access as root. */