mirror of
https://github.com/raspberrypi/linux.git
synced 2025-12-06 10:00:17 +00:00
bcma: Fix memory leak for internally-handled cores
[ Upstream commitb63aed3ff1] kmemleak reported that dev_name() of internally-handled cores were leaked on driver unbinding. Let's use device_initialize() to take refcounts for them and put_device() to properly free the related stuff. While looking at it, there's another potential issue for those which should be *registered* into driver core. If device_register() failed, we put device once and freed bcma_device structures. In bcma_unregister_cores(), they're treated as unregistered and we hit both UAF and double-free. That smells not good and has also been fixed now. Fixes:ab54bc8460("bcma: fill core details for every device") Signed-off-by: Zenghui Yu <yuzenghui@huawei.com> Signed-off-by: Kalle Valo <kvalo@codeaurora.org> Link: https://lore.kernel.org/r/20210727025232.663-2-yuzenghui@huawei.com Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
26fae720c1
commit
e68128e078
@@ -236,6 +236,7 @@ EXPORT_SYMBOL(bcma_core_irq);
|
|||||||
|
|
||||||
void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core)
|
void bcma_prepare_core(struct bcma_bus *bus, struct bcma_device *core)
|
||||||
{
|
{
|
||||||
|
device_initialize(&core->dev);
|
||||||
core->dev.release = bcma_release_core_dev;
|
core->dev.release = bcma_release_core_dev;
|
||||||
core->dev.bus = &bcma_bus_type;
|
core->dev.bus = &bcma_bus_type;
|
||||||
dev_set_name(&core->dev, "bcma%d:%d", bus->num, core->core_index);
|
dev_set_name(&core->dev, "bcma%d:%d", bus->num, core->core_index);
|
||||||
@@ -277,11 +278,10 @@ static void bcma_register_core(struct bcma_bus *bus, struct bcma_device *core)
|
|||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = device_register(&core->dev);
|
err = device_add(&core->dev);
|
||||||
if (err) {
|
if (err) {
|
||||||
bcma_err(bus, "Could not register dev for core 0x%03X\n",
|
bcma_err(bus, "Could not register dev for core 0x%03X\n",
|
||||||
core->id.id);
|
core->id.id);
|
||||||
put_device(&core->dev);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
core->dev_registered = true;
|
core->dev_registered = true;
|
||||||
@@ -372,7 +372,7 @@ void bcma_unregister_cores(struct bcma_bus *bus)
|
|||||||
/* Now noone uses internally-handled cores, we can free them */
|
/* Now noone uses internally-handled cores, we can free them */
|
||||||
list_for_each_entry_safe(core, tmp, &bus->cores, list) {
|
list_for_each_entry_safe(core, tmp, &bus->cores, list) {
|
||||||
list_del(&core->list);
|
list_del(&core->list);
|
||||||
kfree(core);
|
put_device(&core->dev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user