]> www.infradead.org Git - users/hch/misc.git/commitdiff
mctp: Handle error of rtnl_register_module().
authorKuniyuki Iwashima <kuniyu@amazon.com>
Tue, 8 Oct 2024 18:47:35 +0000 (11:47 -0700)
committerPaolo Abeni <pabeni@redhat.com>
Thu, 10 Oct 2024 13:39:35 +0000 (15:39 +0200)
Since introduced, mctp has been ignoring the returned value of
rtnl_register_module(), which could fail silently.

Handling the error allows users to view a module as an all-or-nothing
thing in terms of the rtnetlink functionality.  This prevents syzkaller
from reporting spurious errors from its tests, where OOM often occurs
and module is automatically loaded.

Let's handle the errors by rtnl_register_many().

Fixes: 583be982d934 ("mctp: Add device handling and netlink interface")
Fixes: 831119f88781 ("mctp: Add neighbour netlink interface")
Fixes: 06d2f4c583a7 ("mctp: Add netlink route management")
Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Reviewed-by: Jeremy Kerr <jk@codeconstruct.com.au>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
include/net/mctp.h
net/mctp/af_mctp.c
net/mctp/device.c
net/mctp/neigh.c
net/mctp/route.c

index 7b17c52e8ce2a43b09f778874f8871a55bc1a098..28d59ae94ca3b486ccc86d05aed26e998ad50c4d 100644 (file)
@@ -295,7 +295,7 @@ void mctp_neigh_remove_dev(struct mctp_dev *mdev);
 int mctp_routes_init(void);
 void mctp_routes_exit(void);
 
-void mctp_device_init(void);
+int mctp_device_init(void);
 void mctp_device_exit(void);
 
 #endif /* __NET_MCTP_H */
index 43288b408fde3b51726eb6f62137509100d2d410..f6de136008f6f9b029e7dacc2e75dce1cd7fd075 100644 (file)
@@ -756,10 +756,14 @@ static __init int mctp_init(void)
        if (rc)
                goto err_unreg_routes;
 
-       mctp_device_init();
+       rc = mctp_device_init();
+       if (rc)
+               goto err_unreg_neigh;
 
        return 0;
 
+err_unreg_neigh:
+       mctp_neigh_exit();
 err_unreg_routes:
        mctp_routes_exit();
 err_unreg_proto:
index acb97b2574289628ea6ea1da02433eef119e6d8b..85cc5f31f1e7c0a0c3f51c5e924d9424dec27b5a 100644 (file)
@@ -524,25 +524,31 @@ static struct notifier_block mctp_dev_nb = {
        .priority = ADDRCONF_NOTIFY_PRIORITY,
 };
 
-void __init mctp_device_init(void)
+static const struct rtnl_msg_handler mctp_device_rtnl_msg_handlers[] = {
+       {THIS_MODULE, PF_MCTP, RTM_NEWADDR, mctp_rtm_newaddr, NULL, 0},
+       {THIS_MODULE, PF_MCTP, RTM_DELADDR, mctp_rtm_deladdr, NULL, 0},
+       {THIS_MODULE, PF_MCTP, RTM_GETADDR, NULL, mctp_dump_addrinfo, 0},
+};
+
+int __init mctp_device_init(void)
 {
-       register_netdevice_notifier(&mctp_dev_nb);
+       int err;
 
-       rtnl_register_module(THIS_MODULE, PF_MCTP, RTM_GETADDR,
-                            NULL, mctp_dump_addrinfo, 0);
-       rtnl_register_module(THIS_MODULE, PF_MCTP, RTM_NEWADDR,
-                            mctp_rtm_newaddr, NULL, 0);
-       rtnl_register_module(THIS_MODULE, PF_MCTP, RTM_DELADDR,
-                            mctp_rtm_deladdr, NULL, 0);
+       register_netdevice_notifier(&mctp_dev_nb);
        rtnl_af_register(&mctp_af_ops);
+
+       err = rtnl_register_many(mctp_device_rtnl_msg_handlers);
+       if (err) {
+               rtnl_af_unregister(&mctp_af_ops);
+               unregister_netdevice_notifier(&mctp_dev_nb);
+       }
+
+       return err;
 }
 
 void __exit mctp_device_exit(void)
 {
+       rtnl_unregister_many(mctp_device_rtnl_msg_handlers);
        rtnl_af_unregister(&mctp_af_ops);
-       rtnl_unregister(PF_MCTP, RTM_DELADDR);
-       rtnl_unregister(PF_MCTP, RTM_NEWADDR);
-       rtnl_unregister(PF_MCTP, RTM_GETADDR);
-
        unregister_netdevice_notifier(&mctp_dev_nb);
 }
index ffa0f9e0983fba13d3de3b72f35af8357e154a05..590f642413e4ef113a1a9fa96cb548b98cb55621 100644 (file)
@@ -322,22 +322,29 @@ static struct pernet_operations mctp_net_ops = {
        .exit = mctp_neigh_net_exit,
 };
 
+static const struct rtnl_msg_handler mctp_neigh_rtnl_msg_handlers[] = {
+       {THIS_MODULE, PF_MCTP, RTM_NEWNEIGH, mctp_rtm_newneigh, NULL, 0},
+       {THIS_MODULE, PF_MCTP, RTM_DELNEIGH, mctp_rtm_delneigh, NULL, 0},
+       {THIS_MODULE, PF_MCTP, RTM_GETNEIGH, NULL, mctp_rtm_getneigh, 0},
+};
+
 int __init mctp_neigh_init(void)
 {
-       rtnl_register_module(THIS_MODULE, PF_MCTP, RTM_NEWNEIGH,
-                            mctp_rtm_newneigh, NULL, 0);
-       rtnl_register_module(THIS_MODULE, PF_MCTP, RTM_DELNEIGH,
-                            mctp_rtm_delneigh, NULL, 0);
-       rtnl_register_module(THIS_MODULE, PF_MCTP, RTM_GETNEIGH,
-                            NULL, mctp_rtm_getneigh, 0);
-
-       return register_pernet_subsys(&mctp_net_ops);
+       int err;
+
+       err = register_pernet_subsys(&mctp_net_ops);
+       if (err)
+               return err;
+
+       err = rtnl_register_many(mctp_neigh_rtnl_msg_handlers);
+       if (err)
+               unregister_pernet_subsys(&mctp_net_ops);
+
+       return err;
 }
 
-void __exit mctp_neigh_exit(void)
+void mctp_neigh_exit(void)
 {
+       rtnl_unregister_many(mctp_neigh_rtnl_msg_handlers);
        unregister_pernet_subsys(&mctp_net_ops);
-       rtnl_unregister(PF_MCTP, RTM_GETNEIGH);
-       rtnl_unregister(PF_MCTP, RTM_DELNEIGH);
-       rtnl_unregister(PF_MCTP, RTM_NEWNEIGH);
 }
index eefd7834d9a009a98325c391cd9c09696db99db7..597e9cf5aa64445474287a3fee02ba760db15796 100644 (file)
@@ -1474,26 +1474,39 @@ static struct pernet_operations mctp_net_ops = {
        .exit = mctp_routes_net_exit,
 };
 
+static const struct rtnl_msg_handler mctp_route_rtnl_msg_handlers[] = {
+       {THIS_MODULE, PF_MCTP, RTM_NEWROUTE, mctp_newroute, NULL, 0},
+       {THIS_MODULE, PF_MCTP, RTM_DELROUTE, mctp_delroute, NULL, 0},
+       {THIS_MODULE, PF_MCTP, RTM_GETROUTE, NULL, mctp_dump_rtinfo, 0},
+};
+
 int __init mctp_routes_init(void)
 {
+       int err;
+
        dev_add_pack(&mctp_packet_type);
 
-       rtnl_register_module(THIS_MODULE, PF_MCTP, RTM_GETROUTE,
-                            NULL, mctp_dump_rtinfo, 0);
-       rtnl_register_module(THIS_MODULE, PF_MCTP, RTM_NEWROUTE,
-                            mctp_newroute, NULL, 0);
-       rtnl_register_module(THIS_MODULE, PF_MCTP, RTM_DELROUTE,
-                            mctp_delroute, NULL, 0);
+       err = register_pernet_subsys(&mctp_net_ops);
+       if (err)
+               goto err_pernet;
+
+       err = rtnl_register_many(mctp_route_rtnl_msg_handlers);
+       if (err)
+               goto err_rtnl;
 
-       return register_pernet_subsys(&mctp_net_ops);
+       return 0;
+
+err_rtnl:
+       unregister_pernet_subsys(&mctp_net_ops);
+err_pernet:
+       dev_remove_pack(&mctp_packet_type);
+       return err;
 }
 
 void mctp_routes_exit(void)
 {
+       rtnl_unregister_many(mctp_route_rtnl_msg_handlers);
        unregister_pernet_subsys(&mctp_net_ops);
-       rtnl_unregister(PF_MCTP, RTM_DELROUTE);
-       rtnl_unregister(PF_MCTP, RTM_NEWROUTE);
-       rtnl_unregister(PF_MCTP, RTM_GETROUTE);
        dev_remove_pack(&mctp_packet_type);
 }