Skip to content

Commit e79c6a4

Browse files
dtordavem330
authored andcommitted
net: make net namespace sysctls belong to container's owner
If net namespace is attached to a user namespace let's make container's root owner of sysctls affecting said network namespace instead of global root. This also allows us to clean up net_ctl_permissions() because we do not need to fudge permissions anymore for the container's owner since it now owns the objects in question. Acked-by: "Eric W. Biederman" <[email protected]> Signed-off-by: Dmitry Torokhov <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent c110486 commit e79c6a4

File tree

3 files changed

+29
-9
lines changed

3 files changed

+29
-9
lines changed

fs/proc/proc_sysctl.c

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -430,6 +430,7 @@ static int sysctl_perm(struct ctl_table_header *head, struct ctl_table *table, i
430430
static struct inode *proc_sys_make_inode(struct super_block *sb,
431431
struct ctl_table_header *head, struct ctl_table *table)
432432
{
433+
struct ctl_table_root *root = head->root;
433434
struct inode *inode;
434435
struct proc_inode *ei;
435436

@@ -457,6 +458,10 @@ static struct inode *proc_sys_make_inode(struct super_block *sb,
457458
if (is_empty_dir(head))
458459
make_empty_dir_inode(inode);
459460
}
461+
462+
if (root->set_ownership)
463+
root->set_ownership(head, table, &inode->i_uid, &inode->i_gid);
464+
460465
out:
461466
return inode;
462467
}

include/linux/sysctl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <linux/rcupdate.h>
2626
#include <linux/wait.h>
2727
#include <linux/rbtree.h>
28+
#include <linux/uidgid.h>
2829
#include <uapi/linux/sysctl.h>
2930

3031
/* For the /proc/sys support */
@@ -157,6 +158,9 @@ struct ctl_table_root {
157158
struct ctl_table_set default_set;
158159
struct ctl_table_set *(*lookup)(struct ctl_table_root *root,
159160
struct nsproxy *namespaces);
161+
void (*set_ownership)(struct ctl_table_header *head,
162+
struct ctl_table *table,
163+
kuid_t *uid, kgid_t *gid);
160164
int (*permissions)(struct ctl_table_header *head, struct ctl_table *table);
161165
};
162166

net/sysctl_net.c

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,26 +42,37 @@ static int net_ctl_permissions(struct ctl_table_header *head,
4242
struct ctl_table *table)
4343
{
4444
struct net *net = container_of(head->set, struct net, sysctls);
45-
kuid_t root_uid = make_kuid(net->user_ns, 0);
46-
kgid_t root_gid = make_kgid(net->user_ns, 0);
4745

4846
/* Allow network administrator to have same access as root. */
49-
if (ns_capable_noaudit(net->user_ns, CAP_NET_ADMIN) ||
50-
uid_eq(root_uid, current_euid())) {
47+
if (ns_capable(net->user_ns, CAP_NET_ADMIN)) {
5148
int mode = (table->mode >> 6) & 7;
5249
return (mode << 6) | (mode << 3) | mode;
5350
}
54-
/* Allow netns root group to have the same access as the root group */
55-
if (in_egroup_p(root_gid)) {
56-
int mode = (table->mode >> 3) & 7;
57-
return (mode << 3) | mode;
58-
}
51+
5952
return table->mode;
6053
}
6154

55+
static void net_ctl_set_ownership(struct ctl_table_header *head,
56+
struct ctl_table *table,
57+
kuid_t *uid, kgid_t *gid)
58+
{
59+
struct net *net = container_of(head->set, struct net, sysctls);
60+
kuid_t ns_root_uid;
61+
kgid_t ns_root_gid;
62+
63+
ns_root_uid = make_kuid(net->user_ns, 0);
64+
if (uid_valid(ns_root_uid))
65+
*uid = ns_root_uid;
66+
67+
ns_root_gid = make_kgid(net->user_ns, 0);
68+
if (gid_valid(ns_root_gid))
69+
*gid = ns_root_gid;
70+
}
71+
6272
static struct ctl_table_root net_sysctl_root = {
6373
.lookup = net_ctl_header_lookup,
6474
.permissions = net_ctl_permissions,
75+
.set_ownership = net_ctl_set_ownership,
6576
};
6677

6778
static int __net_init sysctl_net_init(struct net *net)

0 commit comments

Comments
 (0)