DORMANTno replies

[PATCH] fsi: aspeed: Fix refcount leak on registration failure

From: Guangshuo Li <hidden>
Date: 2026-07-14 12:33:12
Also in: linux-aspeed, lkml
Subsystem: fsi subsystem, the rest · Maintainers: Eddie James, Linus Torvalds

fsi_master_aspeed_probe() allocates aspeed and passes its embedded
master device to fsi_master_register().

After the master index is allocated, fsi_master_register() calls
device_register(), which initializes master.dev and takes its initial
reference. If device registration fails, the reference remains held
when fsi_master_register() returns an error.

The probe error path then calls kfree(aspeed) directly without dropping
the device reference. This leaves the initialized master.dev reference
stranded and bypasses aspeed_master_release().

Disable the clock and call put_device() when registration fails after
the master index has been allocated. Keep the direct kfree() path for
failures that occur before master.dev is initialized.

This issue was found by a static analysis tool I am developing.

Fixes: 606397d67f41 ("fsi: Add ast2600 master driver")
Signed-off-by: Guangshuo Li <redacted>
---
 drivers/fsi/fsi-master-aspeed.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/drivers/fsi/fsi-master-aspeed.c b/drivers/fsi/fsi-master-aspeed.c
index aa1380cdff33..2a54b6fa3394 100644
--- a/drivers/fsi/fsi-master-aspeed.c
+++ b/drivers/fsi/fsi-master-aspeed.c
@@ -626,8 +626,12 @@ static int fsi_master_aspeed_probe(struct platform_device *pdev)
 	aspeed_master_init(aspeed);
 
 	rc = fsi_master_register(&aspeed->master);
-	if (rc)
-		goto err_release;
+	if (rc) {
+		if (aspeed->master.idx < 0)
+			goto err_release;
+
+		goto err_put_master;
+	}
 
 	/* At this point, fsi_master_register performs the device_initialize(),
 	 * and holds the sole reference on master.dev. This means the device
@@ -638,6 +642,10 @@ static int fsi_master_aspeed_probe(struct platform_device *pdev)
 	 */
 	get_device(&aspeed->master.dev);
 	return 0;
+err_put_master:
+	clk_disable_unprepare(aspeed->clk);
+	put_device(&aspeed->master.dev);
+	return rc;
 
 err_release:
 	clk_disable_unprepare(aspeed->clk);
-- 
2.43.0

Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help