Commit 73082d24 authored by Tobin C. Harding's avatar Tobin C. Harding Committed by Greg Kroah-Hartman

bridge: Fix error path for kobject_init_and_add()

[ Upstream commit bdfad5ae ]

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: default avatarTobin C. Harding <tobin@kernel.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
parent 9035a941
...@@ -602,13 +602,15 @@ int br_add_if(struct net_bridge *br, struct net_device *dev, ...@@ -602,13 +602,15 @@ int br_add_if(struct net_bridge *br, struct net_device *dev,
call_netdevice_notifiers(NETDEV_JOIN, dev); call_netdevice_notifiers(NETDEV_JOIN, dev);
err = dev_set_allmulti(dev, 1); err = dev_set_allmulti(dev, 1);
if (err) if (err) {
goto put_back; kfree(p); /* kobject not yet init'd, manually free */
goto err1;
}
err = kobject_init_and_add(&p->kobj, &brport_ktype, &(dev->dev.kobj), err = kobject_init_and_add(&p->kobj, &brport_ktype, &(dev->dev.kobj),
SYSFS_BRIDGE_PORT_ATTR); SYSFS_BRIDGE_PORT_ATTR);
if (err) if (err)
goto err1; goto err2;
err = br_sysfs_addif(p); err = br_sysfs_addif(p);
if (err) if (err)
...@@ -700,12 +702,9 @@ int br_add_if(struct net_bridge *br, struct net_device *dev, ...@@ -700,12 +702,9 @@ int br_add_if(struct net_bridge *br, struct net_device *dev,
sysfs_remove_link(br->ifobj, p->dev->name); sysfs_remove_link(br->ifobj, p->dev->name);
err2: err2:
kobject_put(&p->kobj); kobject_put(&p->kobj);
p = NULL; /* kobject_put frees */
err1:
dev_set_allmulti(dev, -1); dev_set_allmulti(dev, -1);
put_back: err1:
dev_put(dev); dev_put(dev);
kfree(p);
return err; return err;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment