net/af_packet: registration process optimization in packet_init()
authorZiyang Xuan <william.xuanziyang@huawei.com>
Thu, 15 Sep 2022 01:08:35 +0000 (09:08 +0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 21 Sep 2022 11:59:22 +0000 (12:59 +0100)
Now, register_pernet_subsys() and register_netdevice_notifier() are both
after sock_register(). It can create PF_PACKET socket and process socket
once sock_register() successfully. It is possible PF_PACKET socket is
creating but register_pernet_subsys() and register_netdevice_notifier()
are not registered yet. Thus net->packet.sklist_lock and net->packet.sklist
will be accessed without initialization that is done in packet_net_init().
Although this is a low probability scenario.

Move register_pernet_subsys() and register_netdevice_notifier() to the
front in packet_init(). Correspondingly, adjust the unregister process
in packet_exit().

Signed-off-by: Ziyang Xuan <william.xuanziyang@huawei.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/packet/af_packet.c

index 7de46d8313498cf1a93ecc7a87597265d64d35d3..d3f6db350de779f237a48af6c79fef0c6e425da4 100644 (file)
@@ -4725,37 +4725,37 @@ static struct pernet_operations packet_net_ops = {
 
 static void __exit packet_exit(void)
 {
-       unregister_netdevice_notifier(&packet_netdev_notifier);
-       unregister_pernet_subsys(&packet_net_ops);
        sock_unregister(PF_PACKET);
        proto_unregister(&packet_proto);
+       unregister_netdevice_notifier(&packet_netdev_notifier);
+       unregister_pernet_subsys(&packet_net_ops);
 }
 
 static int __init packet_init(void)
 {
        int rc;
 
-       rc = proto_register(&packet_proto, 0);
-       if (rc)
-               goto out;
-       rc = sock_register(&packet_family_ops);
-       if (rc)
-               goto out_proto;
        rc = register_pernet_subsys(&packet_net_ops);
        if (rc)
-               goto out_sock;
+               goto out;
        rc = register_netdevice_notifier(&packet_netdev_notifier);
        if (rc)
                goto out_pernet;
+       rc = proto_register(&packet_proto, 0);
+       if (rc)
+               goto out_notifier;
+       rc = sock_register(&packet_family_ops);
+       if (rc)
+               goto out_proto;
 
        return 0;
 
-out_pernet:
-       unregister_pernet_subsys(&packet_net_ops);
-out_sock:
-       sock_unregister(PF_PACKET);
 out_proto:
        proto_unregister(&packet_proto);
+out_notifier:
+       unregister_netdevice_notifier(&packet_netdev_notifier);
+out_pernet:
+       unregister_pernet_subsys(&packet_net_ops);
 out:
        return rc;
 }