af_unix: Do not call kmemdup() for init_net's sysctl table.
authorKuniyuki Iwashima <kuniyu@amazon.com>
Mon, 27 Jun 2022 23:36:27 +0000 (16:36 -0700)
committerJakub Kicinski <kuba@kernel.org>
Wed, 29 Jun 2022 03:58:57 +0000 (20:58 -0700)
While setting up init_net's sysctl table, we need not duplicate the
global table and can use it directly as ipv4_sysctl_init_net() does.

Unlike IPv4, AF_UNIX does not have a huge sysctl table for now, so it
cannot be a problem, but this patch makes code consistent.

Acked-by: Eric W. Biederman <ebiederm@xmission.com>
Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Link: https://lore.kernel.org/r/20220627233627.51646-1-kuniyu@amazon.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
net/unix/sysctl_net_unix.c

index 01d44e2..3f1fdff 100644 (file)
@@ -26,11 +26,16 @@ int __net_init unix_sysctl_register(struct net *net)
 {
        struct ctl_table *table;
 
-       table = kmemdup(unix_table, sizeof(unix_table), GFP_KERNEL);
-       if (table == NULL)
-               goto err_alloc;
+       if (net_eq(net, &init_net)) {
+               table = unix_table;
+       } else {
+               table = kmemdup(unix_table, sizeof(unix_table), GFP_KERNEL);
+               if (!table)
+                       goto err_alloc;
+
+               table[0].data = &net->unx.sysctl_max_dgram_qlen;
+       }
 
-       table[0].data = &net->unx.sysctl_max_dgram_qlen;
        net->unx.ctl = register_net_sysctl(net, "net/unix", table);
        if (net->unx.ctl == NULL)
                goto err_reg;
@@ -38,7 +43,8 @@ int __net_init unix_sysctl_register(struct net *net)
        return 0;
 
 err_reg:
-       kfree(table);
+       if (net_eq(net, &init_net))
+               kfree(table);
 err_alloc:
        return -ENOMEM;
 }
@@ -49,5 +55,6 @@ void unix_sysctl_unregister(struct net *net)
 
        table = net->unx.ctl->ctl_table_arg;
        unregister_net_sysctl_table(net->unx.ctl);
-       kfree(table);
+       if (!net_eq(net, &init_net))
+               kfree(table);
 }