[PATCH v14 2/8] i3c: master: Fix IBI request and free cleanup paths
Lakshay Piplani <[email protected]> Tue, 14 Jul 2026 14:50:47 +0530
| Newsgroups | org.infradead.lists.linux-i3c,org.kernel.vger.linux-devicetree,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <[email protected]> |
i3c_dev_request_ibi_locked() allocates the generic IBI object and its workqueue before calling the controller request_ibi() callback. If the callback fails, destroy the workqueue before freeing the IBI object. Also, a controller callback may clear dev->ibi while forwarding the request or free operation to another controller. Avoid touching dev->ibi after the callback if it has already been cleared. This prevents a workqueue leak in the request failure path and avoids NULL pointer dereference in the free path when the callback has already released the IBI object. Signed-off-by: Lakshay Piplani <[email protected]> Signed-off-by: Vikash Bansal <[email protected]> Signed-off-by: Aman Kumar Pandey <[email protected]> --- Changes in v14: - Destroy the allocated IBI workqueue when request_ibi() callback fails - Avoid touching dev->ibi after request/free callbacks if a forwarding controller callback has already cleared it --- --- drivers/i3c/master.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c index 2cb94face156..01c6e048485c 100644 --- a/drivers/i3c/master.c +++ b/drivers/i3c/master.c @@ -3499,8 +3499,18 @@ int i3c_dev_request_ibi_locked(struct i3c_dev_desc *dev, dev->ibi = ibi; ret = master->ops->request_ibi(dev, req); - if (ret) { - kfree(ibi); + + /* + * The controller callback may have already released and cleared dev->ibi + * when the request is forwarded by a virtual controller. Only clean up the + * IBI object if the callback left dev->ibi valid. + */ + if (ret && dev->ibi) { + /* Avoid leaking the workqueue allocated for this IBI request. */ + if (dev->ibi->wq) + destroy_workqueue(dev->ibi->wq); + + kfree(dev->ibi); dev->ibi = NULL; } @@ -3540,6 +3550,13 @@ void i3c_dev_free_ibi_locked(struct i3c_dev_desc *dev) master->ops->free_ibi(dev); + /* + * The controller callback may have already released dev->ibi, for example + * when the request was forwarded by a virtual controller. + */ + if (!dev->ibi) + return; + if (dev->ibi->wq) { destroy_workqueue(dev->ibi->wq); dev->ibi->wq = NULL; -- 2.25.1 -- linux-i3c mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-i3c