summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYang Yingliang <yangyingliang@huawei.com>2023-11-29 17:34:08 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2023-12-08 08:44:26 +0100
commit4d7d14c69667eb064998c427fe1308a1c63a524a (patch)
treeabbbecd2241511032f243aab9dc600689ba1dbbc
parent1eaa188f7fecec89364f305bc227748b1d908fda (diff)
firewire: core: fix possible memory leak in create_units()
commit 891e0eab32a57fca4d36c5162628eb0bcb1f0edf upstream. If device_register() fails, the refcount of device is not 0, the name allocated in dev_set_name() is leaked. To fix this by calling put_device(), so that it will be freed in callback function kobject_cleanup(). unreferenced object 0xffff9d99035c7a90 (size 8): comm "systemd-udevd", pid 168, jiffies 4294672386 (age 152.089s) hex dump (first 8 bytes): 66 77 30 2e 30 00 ff ff fw0.0... backtrace: [<00000000e1d62bac>] __kmem_cache_alloc_node+0x1e9/0x360 [<00000000bbeaff31>] __kmalloc_node_track_caller+0x44/0x1a0 [<00000000491f2fb4>] kvasprintf+0x67/0xd0 [<000000005b960ddc>] kobject_set_name_vargs+0x1e/0x90 [<00000000427ac591>] dev_set_name+0x4e/0x70 [<000000003b4e447d>] create_units+0xc5/0x110 fw_unit_release() will be called in the error path, move fw_device_get() before calling device_register() to keep balanced with fw_device_put() in fw_unit_release(). Cc: stable@vger.kernel.org Fixes: 1fa5ae857bb1 ("driver core: get rid of struct device's bus_id string array") Fixes: a1f64819fe9f ("firewire: struct device - replace bus_id with dev_name(), dev_set_name()") Signed-off-by: Yang Yingliang <yangyingliang@huawei.com> Signed-off-by: Takashi Sakamoto <o-takashi@sakamocchi.jp> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/firewire/core-device.c11
1 files changed, 4 insertions, 7 deletions
diff --git a/drivers/firewire/core-device.c b/drivers/firewire/core-device.c
index b785e936244f..6950b033db79 100644
--- a/drivers/firewire/core-device.c
+++ b/drivers/firewire/core-device.c
@@ -719,14 +719,11 @@ static void create_units(struct fw_device *device)
fw_unit_attributes,
&unit->attribute_group);
- if (device_register(&unit->device) < 0)
- goto skip_unit;
-
fw_device_get(device);
- continue;
-
- skip_unit:
- kfree(unit);
+ if (device_register(&unit->device) < 0) {
+ put_device(&unit->device);
+ continue;
+ }
}
}