[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