net: bridge: fix net device refcount tracking issue in error path
authorEric Dumazet <edumazet@google.com>
Wed, 12 Jan 2022 12:53:00 +0000 (04:53 -0800)
committerDavid S. Miller <davem@davemloft.net>
Wed, 12 Jan 2022 14:44:18 +0000 (14:44 +0000)
I left one dev_put() in br_add_if() error path and sure enough
syzbot found its way.

As the tracker is allocated in new_nbp(), we must make sure
to properly free it.

We have to call dev_put_track(dev, &p->dev_tracker) before
@p object is freed, of course. This is not an issue because
br_add_if() owns a reference on @dev.

Fixes: b2dcdc7f731d ("net: bridge: add net device refcount tracker")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: syzbot <syzkaller@googlegroups.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/bridge/br_if.c

index a52ad81..55f47ca 100644 (file)
@@ -615,6 +615,7 @@ int br_add_if(struct net_bridge *br, struct net_device *dev,
        err = dev_set_allmulti(dev, 1);
        if (err) {
                br_multicast_del_port(p);
+               dev_put_track(dev, &p->dev_tracker);
                kfree(p);       /* kobject not yet init'd, manually free */
                goto err1;
        }
@@ -724,10 +725,10 @@ err3:
        sysfs_remove_link(br->ifobj, p->dev->name);
 err2:
        br_multicast_del_port(p);
+       dev_put_track(dev, &p->dev_tracker);
        kobject_put(&p->kobj);
        dev_set_allmulti(dev, -1);
 err1:
-       dev_put(dev);
        return err;
 }