0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <linux/mm.h>
0016 #include <linux/export.h>
0017 #include <linux/sysctl.h>
0018 #include <linux/nsproxy.h>
0019
0020 #include <net/sock.h>
0021
0022 #ifdef CONFIG_INET
0023 #include <net/ip.h>
0024 #endif
0025
0026 #ifdef CONFIG_NET
0027 #include <linux/if_ether.h>
0028 #endif
0029
0030 static struct ctl_table_set *
0031 net_ctl_header_lookup(struct ctl_table_root *root)
0032 {
0033 return ¤t->nsproxy->net_ns->sysctls;
0034 }
0035
0036 static int is_seen(struct ctl_table_set *set)
0037 {
0038 return ¤t->nsproxy->net_ns->sysctls == set;
0039 }
0040
0041
0042 static int net_ctl_permissions(struct ctl_table_header *head,
0043 struct ctl_table *table)
0044 {
0045 struct net *net = container_of(head->set, struct net, sysctls);
0046
0047
0048 if (ns_capable_noaudit(net->user_ns, CAP_NET_ADMIN)) {
0049 int mode = (table->mode >> 6) & 7;
0050 return (mode << 6) | (mode << 3) | mode;
0051 }
0052
0053 return table->mode;
0054 }
0055
0056 static void net_ctl_set_ownership(struct ctl_table_header *head,
0057 struct ctl_table *table,
0058 kuid_t *uid, kgid_t *gid)
0059 {
0060 struct net *net = container_of(head->set, struct net, sysctls);
0061 kuid_t ns_root_uid;
0062 kgid_t ns_root_gid;
0063
0064 ns_root_uid = make_kuid(net->user_ns, 0);
0065 if (uid_valid(ns_root_uid))
0066 *uid = ns_root_uid;
0067
0068 ns_root_gid = make_kgid(net->user_ns, 0);
0069 if (gid_valid(ns_root_gid))
0070 *gid = ns_root_gid;
0071 }
0072
0073 static struct ctl_table_root net_sysctl_root = {
0074 .lookup = net_ctl_header_lookup,
0075 .permissions = net_ctl_permissions,
0076 .set_ownership = net_ctl_set_ownership,
0077 };
0078
0079 static int __net_init sysctl_net_init(struct net *net)
0080 {
0081 setup_sysctl_set(&net->sysctls, &net_sysctl_root, is_seen);
0082 return 0;
0083 }
0084
0085 static void __net_exit sysctl_net_exit(struct net *net)
0086 {
0087 retire_sysctl_set(&net->sysctls);
0088 }
0089
0090 static struct pernet_operations sysctl_pernet_ops = {
0091 .init = sysctl_net_init,
0092 .exit = sysctl_net_exit,
0093 };
0094
0095 static struct ctl_table_header *net_header;
0096 __init int net_sysctl_init(void)
0097 {
0098 static struct ctl_table empty[1];
0099 int ret = -ENOMEM;
0100
0101
0102
0103
0104 net_header = register_sysctl("net", empty);
0105 if (!net_header)
0106 goto out;
0107 ret = register_pernet_subsys(&sysctl_pernet_ops);
0108 if (ret)
0109 goto out1;
0110 out:
0111 return ret;
0112 out1:
0113 unregister_sysctl_table(net_header);
0114 net_header = NULL;
0115 goto out;
0116 }
0117
0118
0119
0120
0121
0122
0123
0124 static void ensure_safe_net_sysctl(struct net *net, const char *path,
0125 struct ctl_table *table)
0126 {
0127 struct ctl_table *ent;
0128
0129 pr_debug("Registering net sysctl (net %p): %s\n", net, path);
0130 for (ent = table; ent->procname; ent++) {
0131 unsigned long addr;
0132 const char *where;
0133
0134 pr_debug(" procname=%s mode=%o proc_handler=%ps data=%p\n",
0135 ent->procname, ent->mode, ent->proc_handler, ent->data);
0136
0137
0138 if ((ent->mode & 0222) == 0) {
0139 pr_debug(" Not writable by anyone\n");
0140 continue;
0141 }
0142
0143
0144 addr = (unsigned long)ent->data;
0145 if (is_module_address(addr))
0146 where = "module";
0147 else if (is_kernel_core_data(addr))
0148 where = "kernel";
0149 else
0150 continue;
0151
0152
0153
0154
0155 WARN(1, "sysctl %s/%s: data points to %s global data: %ps\n",
0156 path, ent->procname, where, ent->data);
0157
0158
0159 ent->mode &= ~0222;
0160 }
0161 }
0162
0163 struct ctl_table_header *register_net_sysctl(struct net *net,
0164 const char *path, struct ctl_table *table)
0165 {
0166 if (!net_eq(net, &init_net))
0167 ensure_safe_net_sysctl(net, path, table);
0168
0169 return __register_sysctl_table(&net->sysctls, path, table);
0170 }
0171 EXPORT_SYMBOL_GPL(register_net_sysctl);
0172
0173 void unregister_net_sysctl_table(struct ctl_table_header *header)
0174 {
0175 unregister_sysctl_table(header);
0176 }
0177 EXPORT_SYMBOL_GPL(unregister_net_sysctl_table);