Toshiaki Makita
2017-Dec-18 02:24 UTC
[Bridge] [PATCH net] net: bridge: fix early call to br_stp_change_bridge_id
On 2017/12/16 20:31, Nikolay Aleksandrov wrote:> The early call to br_stp_change_bridge_id in bridge's newlink can cause > a memory leak if an error occurs during the newlink because the fdb > entries are not cleaned up if a different lladdr was specified, also > another minor issue is that it generates fdb notifications with > ifindex = 0. To remove this special case the call is done after netdev > register and we cleanup any bridge fdb entries on changelink error. > That also doesn't slow down normal bridge removal, alternative is to call > it in its ndo_uninit....> Fixes: a4b816d8ba1c ("bridge: Change local fdb entries whenever mac address of bridge device changes") > Signed-off-by: Nikolay Aleksandrov <nikolay at cumulusnetworks.com> > --- > Consequently this also would fix the null ptr deref due to the rhashtable > not being initialized in net-next when br_stp_change_bridge_id is called. > > Toshiaki, any reason you called br_stp_change_bridge_id before > register_netdevice when you introduced it in 30313a3d5794 ?Thank you for taking care of this. It's my bad. I just missed the problem.> net/bridge/br_netlink.c | 14 +++++++++----- > 1 file changed, 9 insertions(+), 5 deletions(-) > > diff --git a/net/bridge/br_netlink.c b/net/bridge/br_netlink.c > index d0ef0a8e8831..b0362cadb7c8 100644 > --- a/net/bridge/br_netlink.c > +++ b/net/bridge/br_netlink.c > @@ -1262,19 +1262,23 @@ static int br_dev_newlink(struct net *src_net, struct net_device *dev,...> err = br_changelink(dev, tb, data, extack); > - if (err) > + if (err) { > + /* clean possible fdbs from br_stp_change_bridge_id above */ > + br_fdb_delete_by_port(br, NULL, 0, 1);Don't we need to call br_dev_delete (br_link_ops.dellink) after successful register instead of br_fdb_delete? Particularly I'm wondering if not calling br_sysfs_delbr() is ok or not. -- Toshiaki Makita
Nikolay Aleksandrov
2017-Dec-18 14:22 UTC
[Bridge] [PATCH net] net: bridge: fix early call to br_stp_change_bridge_id
On 12/18/2017 04:24 AM, Toshiaki Makita wrote:> On 2017/12/16 20:31, Nikolay Aleksandrov wrote:[snip]> ... >> err = br_changelink(dev, tb, data, extack); >> - if (err) >> + if (err) { >> + /* clean possible fdbs from br_stp_change_bridge_id above */ >> + br_fdb_delete_by_port(br, NULL, 0, 1); > > Don't we need to call br_dev_delete (br_link_ops.dellink) after > successful register instead of br_fdb_delete? > Particularly I'm wondering if not calling br_sysfs_delbr() is ok or not. >Funny, that is actually the only reason we need to call it (br_sysfs_delbr). :-) Good catch, that is another leak - the bridge sysfs entries are registered when NETDEV_REGISTER event happens (register_netdevice) but are not properly cleaned up on error there. This has also been present since the introduction of changelink during newlink, commit: b6677449dff6 ("bridge: netlink: call br_changelink() during br_dev_newlink()") I'll send v2 that does br_dev_delete(dev, NULL) instead of the current cleanup. With kobject debug enabled and that I can see "brif" and the rest of the sysfs files getting freed properly, while before they weren't. Thanks, Nik