[PATCH] fsi: master-hub: fix memory leak on registration failure
From: Guangshuo Li
Date: Sat Sep 19 2026 - 12:35:46 EST
hub_master_probe() allocates hub with kzalloc_obj(), but the probe
failure path does not free it when fsi_master_register() returns an
error.
If master index allocation fails, fsi_master_register() returns before
master.dev is initialized. The current error path only releases the
claimed slave address range, leaving the allocated hub unreachable and
causing a memory leak.
If device registration fails after the master index has been allocated,
device_register() has already initialized master.dev and holds its
initial reference. hub_master_release() is responsible for freeing hub,
but the probe failure path does not drop this reference, so the release
callback is never invoked and the allocated hub is leaked.
Free hub directly when master index allocation fails. When registration
fails after master.dev has been initialized, use put_device() to drop
the device reference and invoke hub_master_release(), which frees hub.
This issue was found by manual code inspection.
Fixes: e0c24bddf07c ("fsi: master: Clarify master lifetimes & fix use-after-free in hub master")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Guangshuo Li <lgs201920130244@xxxxxxxxx>
---
drivers/fsi/fsi-master-hub.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/drivers/fsi/fsi-master-hub.c b/drivers/fsi/fsi-master-hub.c
index e5ac9025762e..2cc0c40717fe 100644
--- a/drivers/fsi/fsi-master-hub.c
+++ b/drivers/fsi/fsi-master-hub.c
@@ -240,8 +240,13 @@ static int hub_master_probe(struct fsi_device *fsi_dev)
hub_master_init(hub);
rc = fsi_master_register(&hub->master);
- if (rc)
+ if (rc) {
+ if (hub->master.idx < 0)
+ goto err_free_hub;
+
+ put_device(&hub->master.dev);
goto err_release;
+ }
/* At this point, fsi_master_register performs the device_initialize(),
* and holds the sole reference on master.dev. This means the device
@@ -253,6 +258,8 @@ static int hub_master_probe(struct fsi_device *fsi_dev)
get_device(&hub->master.dev);
return 0;
+err_free_hub:
+ kfree(hub);
err_release:
fsi_slave_release_range(fsi_dev->slave, FSI_HUB_LINK_OFFSET,
FSI_HUB_LINK_SIZE * links);
--
2.43.0