diff options
| author | Yuho Choi <dbgh9129@gmail.com> | 2026-06-03 15:51:42 -0400 |
|---|---|---|
| committer | Manivannan Sadhasivam <mani@kernel.org> | 2026-07-09 08:06:26 +0200 |
| commit | 6f12862600bb70e599a614d706a095ea5f8f9858 (patch) | |
| tree | 01c06cb22fa145a8c5fdd839a6fa8bfe12824d8b | |
| parent | 22568e8f13a42ab69b7d624741768cbf15dded74 (diff) | |
bus: mhi: ep: Fix device refcount leak in the error path of MHI device creation
mhi_ep_create_device() takes one device reference for the UL channel and
another for the DL channel after allocating the transfer device. These
references are normally released by mhi_ep_destroy_device() before the
device itself is removed.
If dev_set_name() or device_add() fails, the error path currently drops
only one reference. The remaining channel references keep the device
from being released and leave the channels associated with a device that
was never registered.
Route both failures through a common unwind path that drops the DL
channel reference, the UL channel reference, and the initial reference
from device_initialize().
Fixes: 297c77a0f273 ("bus: mhi: ep: Add support for creating and destroying MHI EP devices")
Signed-off-by: Yuho Choi <dbgh9129@gmail.com>
Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
Link: https://patch.msgid.link/20260603195142.2189386-1-dbgh9129@gmail.com
| -rw-r--r-- | drivers/bus/mhi/ep/main.c | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/drivers/bus/mhi/ep/main.c b/drivers/bus/mhi/ep/main.c index 9db2a2a2c913..43d680778704 100644 --- a/drivers/bus/mhi/ep/main.c +++ b/drivers/bus/mhi/ep/main.c @@ -1341,14 +1341,19 @@ static int mhi_ep_create_device(struct mhi_ep_cntrl *mhi_cntrl, u32 ch_id) ret = dev_set_name(&mhi_dev->dev, "%s_%s", dev_name(&mhi_cntrl->mhi_dev->dev), mhi_dev->name); - if (ret) { - put_device(&mhi_dev->dev); - return ret; - } + if (ret) + goto err_put_channels; ret = device_add(&mhi_dev->dev); if (ret) - put_device(&mhi_dev->dev); + goto err_put_channels; + + return 0; + +err_put_channels: + put_device(&mhi_dev->dev); /* DL channel reference */ + put_device(&mhi_dev->dev); /* UL channel reference */ + put_device(&mhi_dev->dev); /* device_initialize() reference */ return ret; } |
