diff options
author | Eric W. Biederman <ebiederm@xmission.com> | 2012-11-15 22:02:58 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2012-11-18 20:30:55 -0500 |
commit | 73f7ef435934e952c1d70d83d69921ea5d1f6bd4 (patch) | |
tree | a5d0bbe5e1154eaec96f859507e90bae4b34d0b9 | |
parent | d328b836823cd4a76611a45f52e208f8ce3d75d7 (diff) |
sysctl: Pass useful parameters to sysctl permissions
- 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>
-rw-r--r-- | fs/proc/proc_sysctl.c | 9 | ||||
-rw-r--r-- | include/linux/sysctl.h | 3 | ||||
-rw-r--r-- | net/sysctl_net.c | 3 |
3 files changed, 7 insertions, 8 deletions
diff --git a/fs/proc/proc_sysctl.c b/fs/proc/proc_sysctl.c index a781bdf06694..701580ddfcc3 100644 --- a/fs/proc/proc_sysctl.c +++ b/fs/proc/proc_sysctl.c | |||
@@ -378,12 +378,13 @@ static int test_perm(int mode, int op) | |||
378 | return -EACCES; | 378 | return -EACCES; |
379 | } | 379 | } |
380 | 380 | ||
381 | static int sysctl_perm(struct ctl_table_root *root, struct ctl_table *table, int op) | 381 | static int sysctl_perm(struct ctl_table_header *head, struct ctl_table *table, int op) |
382 | { | 382 | { |
383 | struct ctl_table_root *root = head->root; | ||
383 | int mode; | 384 | int mode; |
384 | 385 | ||
385 | if (root->permissions) | 386 | if (root->permissions) |
386 | mode = root->permissions(root, current->nsproxy, table); | 387 | mode = root->permissions(head, table); |
387 | else | 388 | else |
388 | mode = table->mode; | 389 | mode = table->mode; |
389 | 390 | ||
@@ -491,7 +492,7 @@ static ssize_t proc_sys_call_handler(struct file *filp, void __user *buf, | |||
491 | * and won't be until we finish. | 492 | * and won't be until we finish. |
492 | */ | 493 | */ |
493 | error = -EPERM; | 494 | error = -EPERM; |
494 | if (sysctl_perm(head->root, table, write ? MAY_WRITE : MAY_READ)) | 495 | if (sysctl_perm(head, table, write ? MAY_WRITE : MAY_READ)) |
495 | goto out; | 496 | goto out; |
496 | 497 | ||
497 | /* if that can happen at all, it should be -EINVAL, not -EISDIR */ | 498 | /* 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) | |||
717 | if (!table) /* global root - r-xr-xr-x */ | 718 | if (!table) /* global root - r-xr-xr-x */ |
718 | error = mask & MAY_WRITE ? -EACCES : 0; | 719 | error = mask & MAY_WRITE ? -EACCES : 0; |
719 | else /* Use the permissions on the sysctl table entry */ | 720 | else /* Use the permissions on the sysctl table entry */ |
720 | error = sysctl_perm(head->root, table, mask & ~MAY_NOT_BLOCK); | 721 | error = sysctl_perm(head, table, mask & ~MAY_NOT_BLOCK); |
721 | 722 | ||
722 | sysctl_head_finish(head); | 723 | sysctl_head_finish(head); |
723 | return error; | 724 | return error; |
diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h index cd844a6a8d5f..14a8ff2de11e 100644 --- a/include/linux/sysctl.h +++ b/include/linux/sysctl.h | |||
@@ -158,8 +158,7 @@ struct ctl_table_root { | |||
158 | struct ctl_table_set default_set; | 158 | struct ctl_table_set default_set; |
159 | struct ctl_table_set *(*lookup)(struct ctl_table_root *root, | 159 | struct ctl_table_set *(*lookup)(struct ctl_table_root *root, |
160 | struct nsproxy *namespaces); | 160 | struct nsproxy *namespaces); |
161 | int (*permissions)(struct ctl_table_root *root, | 161 | int (*permissions)(struct ctl_table_header *head, struct ctl_table *table); |
162 | struct nsproxy *namespaces, struct ctl_table *table); | ||
163 | }; | 162 | }; |
164 | 163 | ||
165 | /* struct ctl_path describes where in the hierarchy a table is added */ | 164 | /* struct ctl_path describes where in the hierarchy a table is added */ |
diff --git a/net/sysctl_net.c b/net/sysctl_net.c index e3a6e37cd1c5..e98f3932bdfb 100644 --- a/net/sysctl_net.c +++ b/net/sysctl_net.c | |||
@@ -38,8 +38,7 @@ static int is_seen(struct ctl_table_set *set) | |||
38 | } | 38 | } |
39 | 39 | ||
40 | /* Return standard mode bits for table entry. */ | 40 | /* Return standard mode bits for table entry. */ |
41 | static int net_ctl_permissions(struct ctl_table_root *root, | 41 | static int net_ctl_permissions(struct ctl_table_header *head, |
42 | struct nsproxy *nsproxy, | ||
43 | struct ctl_table *table) | 42 | struct ctl_table *table) |
44 | { | 43 | { |
45 | /* Allow network administrator to have same access as root. */ | 44 | /* Allow network administrator to have same access as root. */ |