extcon: fix possible name leak in error case in extcon_dev_register()

Message ID 20221124044748.3378955-1-yangyingliang@huawei.com
State New
Headers
Series extcon: fix possible name leak in error case in extcon_dev_register() |

Commit Message

Yang Yingliang Nov. 24, 2022, 4:47 a.m. UTC
  I got the following memory leak report while doing fault injection test:

unreferenced object 0xffff888108cff080 (size 16):
  comm "77-i2c-ptn5150", pid 253, jiffies 4294732125 (age 33.960s)
  hex dump (first 16 bytes):
    65 78 74 63 6f 6e 38 32 00 f0 cf 08 81 88 ff ff  extcon82........
  backtrace:
    [<000000001811fc5c>] __kmalloc_node_track_caller+0x44/0x1b0
    [<000000005bac260d>] kvasprintf+0xb5/0x140
    [<000000000dd1d389>] kvasprintf_const+0x55/0x110
    [<000000000ea8369c>] kobject_set_name_vargs+0x43/0xf0
    [<00000000d89b28c6>] dev_set_name+0xab/0xe0
    [<00000000a55cf990>] extcon_dev_register+0x170/0xea0 [extcon_core]
    [<00000000eb2f186e>] devm_extcon_dev_register+0x48/0xb0 [extcon_core]
    [<0000000077933346>] ptn5150_i2c_probe+0x2f2/0x543 [extcon_ptn5150]

In the error case before device_register(), the name allocated
by dev_set_name() is leaked. Fix this by moving dev_set_name()
to front of device_register(), so it's managed by device core,
and it is freed when the refcount is 0.

Fixes: 806d9dd71ff5 ("Extcon: support multiple states at a device.")
Signed-off-by: Yang Yingliang <yangyingliang@huawei.com>
---
 drivers/extcon/extcon.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
  

Patch

diff --git a/drivers/extcon/extcon.c b/drivers/extcon/extcon.c
index e1c71359b605..f978e5e8e6cf 100644
--- a/drivers/extcon/extcon.c
+++ b/drivers/extcon/extcon.c
@@ -1115,8 +1115,6 @@  int extcon_dev_register(struct extcon_dev *edev)
 			"extcon device name is null\n");
 		return -EINVAL;
 	}
-	dev_set_name(&edev->dev, "extcon%lu",
-			(unsigned long)atomic_inc_return(&edev_no));
 
 	if (edev->max_supported) {
 		char *str;
@@ -1252,6 +1250,8 @@  int extcon_dev_register(struct extcon_dev *edev)
 	dev_set_drvdata(&edev->dev, edev);
 	edev->state = 0;
 
+	dev_set_name(&edev->dev, "extcon%lu",
+		     (unsigned long)atomic_inc_return(&edev_no));
 	ret = device_register(&edev->dev);
 	if (ret) {
 		put_device(&edev->dev);