diff options
-rw-r--r-- | include/net/net_namespace.h | 3 | ||||
-rw-r--r-- | net/sysctl_net.c | 30 |
2 files changed, 33 insertions, 0 deletions
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h index aa540e6be502..8df751b3be55 100644 --- a/include/net/net_namespace.h +++ b/include/net/net_namespace.h | |||
@@ -201,8 +201,11 @@ extern void unregister_pernet_gen_device(int id, struct pernet_operations *); | |||
201 | struct ctl_path; | 201 | struct ctl_path; |
202 | struct ctl_table; | 202 | struct ctl_table; |
203 | struct ctl_table_header; | 203 | struct ctl_table_header; |
204 | |||
204 | extern struct ctl_table_header *register_net_sysctl_table(struct net *net, | 205 | extern struct ctl_table_header *register_net_sysctl_table(struct net *net, |
205 | const struct ctl_path *path, struct ctl_table *table); | 206 | const struct ctl_path *path, struct ctl_table *table); |
207 | extern struct ctl_table_header *register_net_sysctl_rotable( | ||
208 | const struct ctl_path *path, struct ctl_table *table); | ||
206 | extern void unregister_net_sysctl_table(struct ctl_table_header *header); | 209 | extern void unregister_net_sysctl_table(struct ctl_table_header *header); |
207 | 210 | ||
208 | #endif /* __NET_NET_NAMESPACE_H */ | 211 | #endif /* __NET_NET_NAMESPACE_H */ |
diff --git a/net/sysctl_net.c b/net/sysctl_net.c index b4f0525f91af..d8e79162724c 100644 --- a/net/sysctl_net.c +++ b/net/sysctl_net.c | |||
@@ -40,6 +40,27 @@ static struct ctl_table_root net_sysctl_root = { | |||
40 | .lookup = net_ctl_header_lookup, | 40 | .lookup = net_ctl_header_lookup, |
41 | }; | 41 | }; |
42 | 42 | ||
43 | static LIST_HEAD(net_sysctl_ro_tables); | ||
44 | static struct list_head *net_ctl_ro_header_lookup(struct ctl_table_root *root, | ||
45 | struct nsproxy *namespaces) | ||
46 | { | ||
47 | return &net_sysctl_ro_tables; | ||
48 | } | ||
49 | |||
50 | static int net_ctl_ro_header_perms(struct ctl_table_root *root, | ||
51 | struct nsproxy *namespaces, struct ctl_table *table) | ||
52 | { | ||
53 | if (namespaces->net_ns == &init_net) | ||
54 | return table->mode; | ||
55 | else | ||
56 | return table->mode & ~0222; | ||
57 | } | ||
58 | |||
59 | static struct ctl_table_root net_sysctl_ro_root = { | ||
60 | .lookup = net_ctl_ro_header_lookup, | ||
61 | .permissions = net_ctl_ro_header_perms, | ||
62 | }; | ||
63 | |||
43 | static int sysctl_net_init(struct net *net) | 64 | static int sysctl_net_init(struct net *net) |
44 | { | 65 | { |
45 | INIT_LIST_HEAD(&net->sysctl_table_headers); | 66 | INIT_LIST_HEAD(&net->sysctl_table_headers); |
@@ -64,6 +85,7 @@ static __init int sysctl_init(void) | |||
64 | if (ret) | 85 | if (ret) |
65 | goto out; | 86 | goto out; |
66 | register_sysctl_root(&net_sysctl_root); | 87 | register_sysctl_root(&net_sysctl_root); |
88 | register_sysctl_root(&net_sysctl_ro_root); | ||
67 | out: | 89 | out: |
68 | return ret; | 90 | return ret; |
69 | } | 91 | } |
@@ -80,6 +102,14 @@ struct ctl_table_header *register_net_sysctl_table(struct net *net, | |||
80 | } | 102 | } |
81 | EXPORT_SYMBOL_GPL(register_net_sysctl_table); | 103 | EXPORT_SYMBOL_GPL(register_net_sysctl_table); |
82 | 104 | ||
105 | struct ctl_table_header *register_net_sysctl_rotable(const | ||
106 | struct ctl_path *path, struct ctl_table *table) | ||
107 | { | ||
108 | return __register_sysctl_paths(&net_sysctl_ro_root, | ||
109 | &init_nsproxy, path, table); | ||
110 | } | ||
111 | EXPORT_SYMBOL_GPL(register_net_sysctl_rotable); | ||
112 | |||
83 | void unregister_net_sysctl_table(struct ctl_table_header *header) | 113 | void unregister_net_sysctl_table(struct ctl_table_header *header) |
84 | { | 114 | { |
85 | unregister_sysctl_table(header); | 115 | unregister_sysctl_table(header); |