phonet: Handle error of rtnl_register_module().

Before commit addf9b90de ("net: rtnetlink: use rcu to free rtnl
message handlers"), once the first rtnl_register_module() allocated
rtnl_msg_handlers[PF_PHONET], the following calls never failed.

However, after the commit, rtnl_register_module() could fail silently
to allocate rtnl_msg_handlers[PF_PHONET][msgtype] and requires error
handling for each call.

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 use rtnl_register_many() to handle the errors easily.

Fixes: addf9b90de ("net: rtnetlink: use rcu to free rtnl message handlers")
Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Acked-by: Rémi Denis-Courmont <courmisch@gmail.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
This commit is contained in:
Kuniyuki Iwashima 2024-10-08 11:47:37 -07:00 committed by Paolo Abeni
parent 5be2062e30
commit b5e837c860

View File

@ -285,23 +285,17 @@ static int route_dumpit(struct sk_buff *skb, struct netlink_callback *cb)
return err; return err;
} }
static const struct rtnl_msg_handler phonet_rtnl_msg_handlers[] __initdata_or_module = {
{THIS_MODULE, PF_PHONET, RTM_NEWADDR, addr_doit, NULL, 0},
{THIS_MODULE, PF_PHONET, RTM_DELADDR, addr_doit, NULL, 0},
{THIS_MODULE, PF_PHONET, RTM_GETADDR, NULL, getaddr_dumpit, 0},
{THIS_MODULE, PF_PHONET, RTM_NEWROUTE, route_doit, NULL, 0},
{THIS_MODULE, PF_PHONET, RTM_DELROUTE, route_doit, NULL, 0},
{THIS_MODULE, PF_PHONET, RTM_GETROUTE, NULL, route_dumpit,
RTNL_FLAG_DUMP_UNLOCKED},
};
int __init phonet_netlink_register(void) int __init phonet_netlink_register(void)
{ {
int err = rtnl_register_module(THIS_MODULE, PF_PHONET, RTM_NEWADDR, return rtnl_register_many(phonet_rtnl_msg_handlers);
addr_doit, NULL, 0);
if (err)
return err;
/* Further rtnl_register_module() cannot fail */
rtnl_register_module(THIS_MODULE, PF_PHONET, RTM_DELADDR,
addr_doit, NULL, 0);
rtnl_register_module(THIS_MODULE, PF_PHONET, RTM_GETADDR,
NULL, getaddr_dumpit, 0);
rtnl_register_module(THIS_MODULE, PF_PHONET, RTM_NEWROUTE,
route_doit, NULL, 0);
rtnl_register_module(THIS_MODULE, PF_PHONET, RTM_DELROUTE,
route_doit, NULL, 0);
rtnl_register_module(THIS_MODULE, PF_PHONET, RTM_GETROUTE,
NULL, route_dumpit, RTNL_FLAG_DUMP_UNLOCKED);
return 0;
} }