Skip to contentSkip to conversation

coresight: syscfg: Fix memleak on registration failure in cscfg_create_device

PATCH Superseded Miaoqian Lin 2 participants 5 messages Jan 10, 2022 – Feb 1, 2022

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

PATCH 1/1 coresight: syscfg: Fix memleak on registration failure in cscfg_create_device

device_register() calls device_initialize(),
according to doc of device_initialize:

Use put_device() to give up your reference instead of freeing
* @dev directly once you have called this function.

To prevent potential memleak, use put_device() instead call kfree directly.

---
 drivers/hwtracing/coresight/coresight-syscfg.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hwtracing/coresight/coresight-syscfg.c +1 -1
index 43054568430f..007fa1c761a7 100644
@@ -764,7 +764,7 @@ struct device *cscfg_device(void)
 /* Must have a release function or the kernel will complain on module unload */
 static void cscfg_dev_release(struct device *dev)
 {
-	kfree(cscfg_mgr);
+	put_device(dev);
 	cscfg_mgr = NULL;
 }
 
Signature · 7 lines
2.17.1


_______________________________________________
linux-arm-kernel mailing list
[email protected]
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
#1 lore raw

Good morning,

Quoted 5 lines · Miaoqian Lin

device_register() calls device_initialize(),
according to doc of device_initialize:

Use put_device() to give up your reference instead of freeing
* @dev directly once you have called this function.

That is _if_ device_initialize() is called manually. In this instance @dev is registered with device_register() and unregistered with device_unregister(). The latter conforms to the comment you pointed out and calls put_device() as expected.

Thanks,
Mathieu

Quoted 25 lines

To prevent potential memleak, use put_device() instead call kfree directly.

---
 drivers/hwtracing/coresight/coresight-syscfg.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hwtracing/coresight/coresight-syscfg.c +1 -1
index 43054568430f..007fa1c761a7 100644
@@ -764,7 +764,7 @@ struct device *cscfg_device(void)
 /* Must have a release function or the kernel will complain on module unload */
 static void cscfg_dev_release(struct device *dev)
 {
-	kfree(cscfg_mgr);
+	put_device(dev);
 	cscfg_mgr = NULL;
 }
 
Signature · 1 line
2.17.1
#2 lore raw
Quoted 6 lines · Mathieu Poirier

Good morning,

Quoted 3 lines · Miaoqian Lin

device_register() calls device_initialize(),
according to doc of device_initialize:

Quoted 7 lines
Quoted 2 lines

Use put_device() to give up your reference instead of freeing
* @dev directly once you have called this function.

That is _if_ device_initialize() is called manually. In this instance @dev is registered with device_register() and unregistered with device_unregister(). The latter conforms to the comment you pointed out and calls put_device() as expected.

I originally misunderstood the context - you are referring to the failure path in cscfg_create_device(). You are correct about needing to call put_device() but your solution will not work when the module is unloaded properly and device_unregister() is called by way of cscfg_clear_device(). In that case device_unregister() is already calling put_device().

Here simply calling put_device() instead of cscfg_dev_release() in the error path should do just fine. That will call cscfg_dev_release() and the memory allocated for cscfg_mgr will be release.

Quoted 29 lines

Thanks,
Mathieu

Quoted 25 lines

To prevent potential memleak, use put_device() instead call kfree directly.

---
 drivers/hwtracing/coresight/coresight-syscfg.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hwtracing/coresight/coresight-syscfg.c +1 -1
index 43054568430f..007fa1c761a7 100644
@@ -764,7 +764,7 @@ struct device *cscfg_device(void)
 /* Must have a release function or the kernel will complain on module unload */
 static void cscfg_dev_release(struct device *dev)
 {
-	kfree(cscfg_mgr);
+	put_device(dev);
 	cscfg_mgr = NULL;
 }
 
Signature · 1 line
2.17.1
#3 lore raw

PATCH v2 1/1 coresight: syscfg: Fix memleak on registration failure in cscfg_create_device

device_register() calls device_initialize(),
according to doc of device_initialize:

Use put_device() to give up your reference instead of freeing
* @dev directly once you have called this function.

To prevent potential memleak, use put_device() for error handling.

---
Changes in v2:
- simply call put_device() instead of cscfg_dev_release() in the error path of cscfg_create_device.

---
 drivers/hwtracing/coresight/coresight-syscfg.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hwtracing/coresight/coresight-syscfg.c +1 -1
index 43054568430f..c30989e0675f 100644
@@ -791,7 +791,7 @@ static int cscfg_create_device(void)
 
 	err = device_register(dev);
 	if (err)
-		cscfg_dev_release(dev);
+		put_device(dev);
 
 create_dev_exit_unlock:
 	mutex_unlock(&cscfg_mutex);
Signature · 1 line
2.17.1
#4 lore raw
Quoted 22 lines · Miaoqian Lin

device_register() calls device_initialize(),
according to doc of device_initialize:

Use put_device() to give up your reference instead of freeing
* @dev directly once you have called this function.

To prevent potential memleak, use put_device() for error handling.

---
Changes in v2:
- simply call put_device() instead of cscfg_dev_release() in the error path of cscfg_create_device.

---
 drivers/hwtracing/coresight/coresight-syscfg.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hwtracing/coresight/coresight-syscfg.c +0 -0
index 43054568430f..c30989e0675f 100644

drivers/hwtracing/coresight/coresight-syscfg.c static int cscfg_create_device(void) · line 794

Quoted 5 lines
drivers/hwtracing/coresight/coresight-syscfg.c +1 -1
@@ -791,7 +791,7 @@ static int cscfg_create_device(void)
 
 	err = device_register(dev);
 	if (err)
-		cscfg_dev_release(dev);
+		put_device(dev);

Applied.

Thanks,
Mathieu

Quoted 6 lines
drivers/hwtracing/coresight/coresight-syscfg.c +0 -0
 create_dev_exit_unlock:
 	mutex_unlock(&cscfg_mutex);
Signature · 1 line
2.17.1