Re: [PATCH] i3c: master: Fix info leak and UAF in device unregister path
Frank Li <[email protected]> Thu, 23 Jul 2026 14:25:56 -0400
| Newsgroups | org.infradead.lists.linux-i3c,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <amJctAYeAwPdnyeb@lizhi-Precision-Tower-5810> |
On Thu, Jul 23, 2026 at 10:57:47AM +0300, Adrian Hunter wrote: > i3c_master_unregister_i3c_devs() clears i3cdev->dev->desc before > calling device_unregister(). During device_unregister(), > device_del() emits a KOBJ_REMOVE uevent and unbinds the driver while > the device descriptor is still expected to be valid. As a result, > i3c_device_uevent() and a racing modalias_show() can observe a NULL > desc and fall back to an uninitialized stack struct i3c_device_info, > leaking kernel stack contents in the generated modalias. Driver > .remove() callbacks may also encounter an unexpected NULL desc during > unbind. > > Keep desc valid until device_unregister() has completed. Since > device_unregister() drops the device reference and may free the device, > take an extra reference with get_device() before unregistering. Clear > desc afterwards and release the extra reference with put_device(). > This preserves the release-time invariant that desc must be NULL while > avoiding both the information leak and a potential use-after-free from > writing desc after the device has been released. > > Reported-by: [email protected] > Link: https://lore.kernel.org/linux-i3c/[email protected]/ > Fixes: 3a379bbcea0a ("i3c: Add core I3C infrastructure") > Cc: [email protected] > Signed-off-by: Adrian Hunter <[email protected]> > --- Reviewed-by: Frank Li <[email protected]> > drivers/i3c/master.c | 9 +++++---- > 1 file changed, 5 insertions(+), 4 deletions(-) > > diff --git a/drivers/i3c/master.c b/drivers/i3c/master.c > index 659c14c2c192..433dc7531701 100644 > --- a/drivers/i3c/master.c > +++ b/drivers/i3c/master.c > @@ -3083,11 +3083,12 @@ static void i3c_master_unregister_i3c_devs(struct i3c_master_controller *master) > if (!i3cdev->dev) > continue; > > - i3cdev->dev->desc = NULL; > - if (device_is_registered(&i3cdev->dev->dev)) > + if (device_is_registered(&i3cdev->dev->dev)) { > + get_device(&i3cdev->dev->dev); > device_unregister(&i3cdev->dev->dev); > - else > - put_device(&i3cdev->dev->dev); > + } > + i3cdev->dev->desc = NULL; > + put_device(&i3cdev->dev->dev); > i3cdev->dev = NULL; > } > } > -- > 2.53.0 > -- linux-i3c mailing list [email protected] http://lists.infradead.org/mailman/listinfo/linux-i3c