mac802154: fix destructon ordering for ieee802154 devices
[platform/adaptation/renesas_rcar/renesas_kernel.git] / net / sysctl_net.c
index c3e65ae..9bc6db0 100644 (file)
 #include <linux/if_ether.h>
 #endif
 
-#ifdef CONFIG_TR
-#include <linux/if_tr.h>
-#endif
-
 static struct ctl_table_set *
 net_ctl_header_lookup(struct ctl_table_root *root, struct nsproxy *namespaces)
 {
@@ -42,15 +38,24 @@ 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)
 {
+       struct net *net = container_of(head->set, struct net, sysctls);
+       kuid_t root_uid = make_kuid(net->user_ns, 0);
+       kgid_t root_gid = make_kgid(net->user_ns, 0);
+
        /* Allow network administrator to have same access as root. */
-       if (capable(CAP_NET_ADMIN)) {
+       if (ns_capable(net->user_ns, CAP_NET_ADMIN) ||
+           uid_eq(root_uid, current_uid())) {
                int mode = (table->mode >> 6) & 7;
                return (mode << 6) | (mode << 3) | mode;
        }
+       /* Allow netns root group to have the same access as the root group */
+       if (gid_eq(root_gid, current_gid())) {
+               int mode = (table->mode >> 3) & 7;
+               return (mode << 3) | mode;
+       }
        return table->mode;
 }
 
@@ -59,19 +64,6 @@ static struct ctl_table_root net_sysctl_root = {
        .permissions = net_ctl_permissions,
 };
 
-static int net_ctl_ro_header_perms(struct ctl_table_root *root,
-               struct nsproxy *namespaces, struct ctl_table *table)
-{
-       if (net_eq(namespaces->net_ns, &init_net))
-               return table->mode;
-       else
-               return table->mode & ~0222;
-}
-
-static struct ctl_table_root net_sysctl_ro_root = {
-       .permissions = net_ctl_ro_header_perms,
-};
-
 static int __net_init sysctl_net_init(struct net *net)
 {
        setup_sysctl_set(&net->sysctls, &net_sysctl_root, is_seen);
@@ -88,34 +80,32 @@ static struct pernet_operations sysctl_pernet_ops = {
        .exit = sysctl_net_exit,
 };
 
-static __init int net_sysctl_init(void)
+static struct ctl_table_header *net_header;
+__init int net_sysctl_init(void)
 {
-       int ret;
+       static struct ctl_table empty[1];
+       int ret = -ENOMEM;
+       /* Avoid limitations in the sysctl implementation by
+        * registering "/proc/sys/net" as an empty directory not in a
+        * network namespace.
+        */
+       net_header = register_sysctl("net", empty);
+       if (!net_header)
+               goto out;
        ret = register_pernet_subsys(&sysctl_pernet_ops);
        if (ret)
                goto out;
-       setup_sysctl_set(&net_sysctl_ro_root.default_set, &net_sysctl_ro_root, NULL);
-       register_sysctl_root(&net_sysctl_ro_root);
        register_sysctl_root(&net_sysctl_root);
 out:
        return ret;
 }
-subsys_initcall(net_sysctl_init);
-
-struct ctl_table_header *register_net_sysctl_table(struct net *net,
-       const struct ctl_path *path, struct ctl_table *table)
-{
-       return __register_sysctl_paths(&net->sysctls, path, table);
-}
-EXPORT_SYMBOL_GPL(register_net_sysctl_table);
 
-struct ctl_table_header *register_net_sysctl_rotable(const
-               struct ctl_path *path, struct ctl_table *table)
+struct ctl_table_header *register_net_sysctl(struct net *net,
+       const char *path, struct ctl_table *table)
 {
-       return __register_sysctl_paths(&net_sysctl_ro_root.default_set,
-                                       path, table);
+       return __register_sysctl_table(&net->sysctls, path, table);
 }
-EXPORT_SYMBOL_GPL(register_net_sysctl_rotable);
+EXPORT_SYMBOL_GPL(register_net_sysctl);
 
 void unregister_net_sysctl_table(struct ctl_table_header *header)
 {