Skip to content

Commit

Permalink
mctp: Handle error of rtnl_register_module().
Browse files Browse the repository at this point in the history
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: 583be98 ("mctp: Add device handling and netlink interface")
Fixes: 831119f ("mctp: Add neighbour netlink interface")
Fixes: 06d2f4c ("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>
  • Loading branch information
Kuniyuki Iwashima authored and Paolo Abeni committed Oct 10, 2024
1 parent cba5e43 commit d517056
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 36 deletions.
2 changes: 1 addition & 1 deletion include/net/mctp.h
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
6 changes: 5 additions & 1 deletion net/mctp/af_mctp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
30 changes: 18 additions & 12 deletions net/mctp/device.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
31 changes: 19 additions & 12 deletions net/mctp/neigh.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
33 changes: 23 additions & 10 deletions net/mctp/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}

Expand Down

0 comments on commit d517056

Please sign in to comment.