Skip to content

Commit

Permalink
bridge: Handle error of rtnl_register_module().
Browse files Browse the repository at this point in the history
Since introduced, br_vlan_rtnl_init() 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: 8dcea18 ("net: bridge: vlan: add rtm definitions and dump support")
Fixes: f26b296 ("net: bridge: vlan: add new rtm message support")
Fixes: adb3ce9 ("net: bridge: vlan: add del rtm message support")
Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
  • Loading branch information
Kuniyuki Iwashima authored and Paolo Abeni committed Oct 10, 2024
1 parent 78b7b99 commit cba5e43
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 13 deletions.
6 changes: 5 additions & 1 deletion net/bridge/br_netlink.c
Original file line number Diff line number Diff line change
Expand Up @@ -1920,7 +1920,10 @@ int __init br_netlink_init(void)
{
int err;

br_vlan_rtnl_init();
err = br_vlan_rtnl_init();
if (err)
goto out;

rtnl_af_register(&br_af_ops);

err = rtnl_link_register(&br_link_ops);
Expand All @@ -1931,6 +1934,7 @@ int __init br_netlink_init(void)

out_af:
rtnl_af_unregister(&br_af_ops);
out:
return err;
}

Expand Down
5 changes: 3 additions & 2 deletions net/bridge/br_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -1571,7 +1571,7 @@ void br_vlan_get_stats(const struct net_bridge_vlan *v,
void br_vlan_port_event(struct net_bridge_port *p, unsigned long event);
int br_vlan_bridge_event(struct net_device *dev, unsigned long event,
void *ptr);
void br_vlan_rtnl_init(void);
int br_vlan_rtnl_init(void);
void br_vlan_rtnl_uninit(void);
void br_vlan_notify(const struct net_bridge *br,
const struct net_bridge_port *p,
Expand Down Expand Up @@ -1802,8 +1802,9 @@ static inline int br_vlan_bridge_event(struct net_device *dev,
return 0;
}

static inline void br_vlan_rtnl_init(void)
static inline int br_vlan_rtnl_init(void)
{
return 0;
}

static inline void br_vlan_rtnl_uninit(void)
Expand Down
19 changes: 9 additions & 10 deletions net/bridge/br_vlan.c
Original file line number Diff line number Diff line change
Expand Up @@ -2296,19 +2296,18 @@ static int br_vlan_rtm_process(struct sk_buff *skb, struct nlmsghdr *nlh,
return err;
}

void br_vlan_rtnl_init(void)
static const struct rtnl_msg_handler br_vlan_rtnl_msg_handlers[] = {
{THIS_MODULE, PF_BRIDGE, RTM_NEWVLAN, br_vlan_rtm_process, NULL, 0},
{THIS_MODULE, PF_BRIDGE, RTM_DELVLAN, br_vlan_rtm_process, NULL, 0},
{THIS_MODULE, PF_BRIDGE, RTM_GETVLAN, NULL, br_vlan_rtm_dump, 0},
};

int br_vlan_rtnl_init(void)
{
rtnl_register_module(THIS_MODULE, PF_BRIDGE, RTM_GETVLAN, NULL,
br_vlan_rtm_dump, 0);
rtnl_register_module(THIS_MODULE, PF_BRIDGE, RTM_NEWVLAN,
br_vlan_rtm_process, NULL, 0);
rtnl_register_module(THIS_MODULE, PF_BRIDGE, RTM_DELVLAN,
br_vlan_rtm_process, NULL, 0);
return rtnl_register_many(br_vlan_rtnl_msg_handlers);
}

void br_vlan_rtnl_uninit(void)
{
rtnl_unregister(PF_BRIDGE, RTM_GETVLAN);
rtnl_unregister(PF_BRIDGE, RTM_NEWVLAN);
rtnl_unregister(PF_BRIDGE, RTM_DELVLAN);
rtnl_unregister_many(br_vlan_rtnl_msg_handlers);
}

0 comments on commit cba5e43

Please sign in to comment.