net/af_packet: registration process optimization in packet_init()

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>
This commit is contained in:
Ziyang Xuan 2022-09-15 09:08:35 +08:00 committed by David S. Miller
parent 2a566f0148
commit 63b7c2ebcc

View File

@ -4725,37 +4725,37 @@ static struct pernet_operations packet_net_ops = {
static void __exit packet_exit(void) static void __exit packet_exit(void)
{ {
unregister_netdevice_notifier(&packet_netdev_notifier);
unregister_pernet_subsys(&packet_net_ops);
sock_unregister(PF_PACKET); sock_unregister(PF_PACKET);
proto_unregister(&packet_proto); proto_unregister(&packet_proto);
unregister_netdevice_notifier(&packet_netdev_notifier);
unregister_pernet_subsys(&packet_net_ops);
} }
static int __init packet_init(void) static int __init packet_init(void)
{ {
int rc; 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); rc = register_pernet_subsys(&packet_net_ops);
if (rc) if (rc)
goto out_sock; goto out;
rc = register_netdevice_notifier(&packet_netdev_notifier); rc = register_netdevice_notifier(&packet_netdev_notifier);
if (rc) if (rc)
goto out_pernet; 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; return 0;
out_pernet:
unregister_pernet_subsys(&packet_net_ops);
out_sock:
sock_unregister(PF_PACKET);
out_proto: out_proto:
proto_unregister(&packet_proto); proto_unregister(&packet_proto);
out_notifier:
unregister_netdevice_notifier(&packet_netdev_notifier);
out_pernet:
unregister_pernet_subsys(&packet_net_ops);
out: out:
return rc; return rc;
} }