Skip to contentSkip to conversation

ibmebus: fix device reference leaks in sysfs interface

PATCH Applied Johan Hovold 2 participants 8 messages Nov 1, 2016 – Nov 14, 2016

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/4 ibmebus: fix device reference leaks in sysfs interface

Make sure to drop any reference taken by bus_find_device() in the sysfs callbacks that are used to create and destroy devices based on device-tree entries.

Fixes 6bccf755ff53 ("[POWERPC] ibmebus: dynamic addition/removal...)
---
 arch/powerpc/kernel/ibmebus.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
arch/powerpc/kernel/ibmebus.c +6 -2
index 6ca9a2ffaac7..c7d3ff7e101c 100644
@@ -262,6 +262,7 @@ static ssize_t ibmebus_store_probe(struct bus_type *bus,
 				   const char *buf, size_t count)
 {
 	struct device_node *dn = NULL;
+	struct device *dev;
 	char *path;
 	ssize_t rc = 0;
 
@@ -269,8 +270,10 @@ static ssize_t ibmebus_store_probe(struct bus_type *bus,
 	if (!path)
 		return -ENOMEM;
 
-	if (bus_find_device(&ibmebus_bus_type, NULL, path,
-			    ibmebus_match_path)) {
+	dev = bus_find_device(&ibmebus_bus_type, NULL, path,
+			      ibmebus_match_path);
+	if (dev) {
+		put_device(dev);
 		printk(KERN_WARNING "%s: %s has already been probed\n",
 		       __func__, path);
 		rc = -EEXIST;
@@ -307,6 +310,7 @@ static ssize_t ibmebus_store_remove(struct bus_type *bus,
 	if ((dev = bus_find_device(&ibmebus_bus_type, NULL, path,
 				   ibmebus_match_path))) {
 		of_device_unregister(to_platform_device(dev));
+		put_device(dev);
 
 		kfree(path);
 		return count;
Signature · 1 line
2.7.3
#1 lore raw

PATCH 2/4 ibmebus: fix further device reference leaks

Make sure to drop any reference taken by bus_find_device() when creating devices during init and driver registration.

Fixes 55347cc9962f ("[POWERPC] ibmebus: Add device creation...)
---
 arch/powerpc/kernel/ibmebus.c | 8 ++++++--
 1 file changed, 6 insertions(+), 2 deletions(-)
arch/powerpc/kernel/ibmebus.c +6 -2
index c7d3ff7e101c..35f5244782d9 100644
@@ -180,6 +180,7 @@ static int ibmebus_create_device(struct device_node *dn)
 static int ibmebus_create_devices(const struct of_device_id *matches)
 {
 	struct device_node *root, *child;
+	struct device *dev;
 	int ret = 0;
 
 	root = of_find_node_by_path("/");
@@ -188,9 +189,12 @@ static int ibmebus_create_devices(const struct of_device_id *matches)
 		if (!of_match_node(matches, child))
 			continue;
 
-		if (bus_find_device(&ibmebus_bus_type, NULL, child,
-				    ibmebus_match_node))
+		dev = bus_find_device(&ibmebus_bus_type, NULL, child,
+				      ibmebus_match_node);
+		if (dev) {
+			put_device(dev);
 			continue;
+		}
 
 		ret = ibmebus_create_device(child);
 		if (ret) {
Signature · 1 line
2.7.3
#3 lore raw

PATCH 3/4 powerpc/vio: clarify vio_find_node reference counting

In reply to Johan Hovold

Add comment clarifying that vio_find_node() takes a reference to the embedded struct device which needs to be dropped after use.

---
 arch/powerpc/kernel/vio.c | 3 +++
 1 file changed, 3 insertions(+)
arch/powerpc/kernel/vio.c +3 -0
index b3813ddb2fb4..2c8fb3ec989e 100644
@@ -1648,6 +1648,9 @@ static struct vio_dev *vio_find_name(const char *name)
 /**
  * vio_find_node - find an already-registered vio_dev
  * @vnode: device_node of the virtual device we're looking for
+ *
+ * Takes a reference to the embedded struct device which needs to be dropped
+ * after use.
  */
 struct vio_dev *vio_find_node(struct device_node *vnode)
 {
Signature · 1 line
2.7.3
#5 lore raw

PATCH 4/4 powerpc/pci: fix device reference leaks

In reply to Johan Hovold

Make sure to drop any device reference taken by vio_find_node() when adding and removing virtual I/O slots.

Fixes 5eeb8c63a38f ("[PATCH] PCI Hotplug: rpaphp: Move VIO...")
---
 drivers/pci/hotplug/rpadlpar_core.c | 10 +++++++++-
 1 file changed, 9 insertions(+), 1 deletion(-)
drivers/pci/hotplug/rpadlpar_core.c +9 -1
index dc67f39779ec..c614ff7c3bc3 100644
@@ -257,8 +257,13 @@ static int dlpar_add_phb(char *drc_name, struct device_node *dn)
 
 static int dlpar_add_vio_slot(char *drc_name, struct device_node *dn)
 {
-	if (vio_find_node(dn))
+	struct vio_dev *vio_dev;
+
+	vio_dev = vio_find_node(dn);
+	if (vio_dev) {
+		put_device(&vio_dev->dev);
 		return -EINVAL;
+	}
 
 	if (!vio_register_device_node(dn)) {
 		printk(KERN_ERR
@@ -334,6 +339,9 @@ static int dlpar_remove_vio_slot(char *drc_name, struct device_node *dn)
 		return -EINVAL;
 
 	vio_unregister_device(vio_dev);
+
+	put_device(&vio_dev->dev);
+
 	return 0;
 }
 
Signature · 1 line
2.7.3