summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTobin C. Harding <tobin@kernel.org>2019-05-10 12:52:12 +1000
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2019-05-16 09:17:23 +0200
commit28107baf408d32535079e7131b8e6cb555d728e1 (patch)
tree4636ef4b5d390a8b19112906117b5d0bcea89314
parentc0759c18e95d72cc889ff0afca9264e2df2fb45e (diff)
downloadlinux-stable-28107baf408d32535079e7131b8e6cb555d728e1.tar.gz
linux-stable-28107baf408d32535079e7131b8e6cb555d728e1.tar.bz2
linux-stable-28107baf408d32535079e7131b8e6cb555d728e1.zip
bridge: Fix error path for kobject_init_and_add()
[ Upstream commit bdfad5aec1392b93495b77b864d58d7f101dc1c1 ] Currently error return from kobject_init_and_add() is not followed by a call to kobject_put(). This means there is a memory leak. We currently set p to NULL so that kfree() may be called on it as a noop, the code is arguably clearer if we move the kfree() up closer to where it is called (instead of after goto jump). Remove a goto label 'err1' and jump to call to kobject_put() in error return from kobject_init_and_add() fixing the memory leak. Re-name goto label 'put_back' to 'err1' now that we don't use err1, following current nomenclature (err1, err2 ...). Move call to kfree out of the error code at bottom of function up to closer to where memory was allocated. Add comment to clarify call to kfree(). Signed-off-by: Tobin C. Harding <tobin@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--net/bridge/br_if.c13
1 files changed, 6 insertions, 7 deletions
diff --git a/net/bridge/br_if.c b/net/bridge/br_if.c
index ef88729ad3d7..42e4d2b32c60 100644
--- a/net/bridge/br_if.c
+++ b/net/bridge/br_if.c
@@ -460,13 +460,15 @@ int br_add_if(struct net_bridge *br, struct net_device *dev)
call_netdevice_notifiers(NETDEV_JOIN, dev);
err = dev_set_allmulti(dev, 1);
- if (err)
- goto put_back;
+ if (err) {
+ kfree(p); /* kobject not yet init'd, manually free */
+ goto err1;
+ }
err = kobject_init_and_add(&p->kobj, &brport_ktype, &(dev->dev.kobj),
SYSFS_BRIDGE_PORT_ATTR);
if (err)
- goto err1;
+ goto err2;
err = br_sysfs_addif(p);
if (err)
@@ -531,12 +533,9 @@ err3:
sysfs_remove_link(br->ifobj, p->dev->name);
err2:
kobject_put(&p->kobj);
- p = NULL; /* kobject_put frees */
-err1:
dev_set_allmulti(dev, -1);
-put_back:
+err1:
dev_put(dev);
- kfree(p);
return err;
}