]> git.ipfire.org Git - thirdparty/kernel/stable.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)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 17 Oct 2024 13:11:57 +0000 (15:11 +0200)
[ Upstream commit d51705614f668254cc5def7490df76f9680b4659 ]

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>
Signed-off-by: Sasha Levin <sashal@kernel.org>
include/net/mctp.h
net/mctp/af_mctp.c
net/mctp/device.c
net/mctp/neigh.c
net/mctp/route.c

index ffd2c23bd76d56a58b389abd46a69979405ec132..8c225091e46cfb8ea2393365e0943834a1a051cc 100644 (file)
@@ -226,7 +226,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 77137a8627d06745e770361a68353d122ea482f7..0ca031866ce1a3d586ef8f76b0dc73d0acb629f8 100644 (file)
@@ -384,10 +384,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 b9f38e765f619395be2dfbf3c6249e1194c37041..c00a2550e2e0e35c27f72016ec7e19d6bf981f7b 100644 (file)
@@ -399,25 +399,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 90ed2f02d1fb02ebb9fed92105b35840f40d5bb6..bc75a263719c77037e34daec5f3e2ecc023233c7 100644 (file)
@@ -321,22 +321,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 5ef6b3b0a3d99d304c96008c1d42fc427fa6a4ec..48d32bfd38636391f5770126d8a314eac22be2f6 100644 (file)
@@ -1134,25 +1134,38 @@ 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);
 }