diff options
| author | Lovekesh Solanki <lovekeshsolanki00@gmail.com> | 2026-08-25 22:43:43 +0530 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2026-09-01 16:41:43 +0200 |
| commit | dd0eed9e165b1a6292f49e622e3dd0b7d99b106d (patch) | |
| tree | a446ebfb975609f5c1bb74ebfcc555ef629cbbd4 /drivers/usb | |
| parent | 7e07d3e4c389217d7d7171d80edf2e23ac70f1ea (diff) | |
| download | linux-next-dd0eed9e165b1a6292f49e622e3dd0b7d99b106d.tar.gz linux-next-dd0eed9e165b1a6292f49e622e3dd0b7d99b106d.zip | |
USB: gadget: fix NULL pointer dereference in gadget_dev_ioctl()
gadget_dev_ioctl() reads dev->gadget before acquiring dev->lock, but
dev->state is checked after acquiring the lock. Therefore a concurrent
bind can change the device state between these operations, which can
leave ioctl with a stale NULL gadget pointer and causing a NULL pointer
dereference at gadget->ops->ioctl.
Read dev->gadget while holding dev->lock so that the gadget pointer
and device state are sampled consistently.
Cc: stable <stable@kernel.org>
Reported-by: Eulgyu Kim <eulgyukim@snu.ac.kr>
Link: https://lore.kernel.org/all/20260824113510.1141236-1-jjy600901@snu.ac.kr/
Reported-by: Jaeyoung Chung <jjy600901@snu.ac.kr>
Link: https://lore.kernel.org/all/20260824113510.1141236-1-jjy600901@snu.ac.kr/
Signed-off-by: Lovekesh Solanki <lovekeshsolanki00@gmail.com>
Reviewed-by: Alan Stern <stern@rowland.harvard.edu>
Link: https://patch.msgid.link/20260825171343.459630-1-lovekeshsolanki00@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/usb')
| -rw-r--r-- | drivers/usb/gadget/legacy/inode.c | 3 |
1 files changed, 2 insertions, 1 deletions
diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index db961aaa3740..67c6ffaf4f72 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -1260,10 +1260,11 @@ out: static long gadget_dev_ioctl (struct file *fd, unsigned code, unsigned long value) { struct dev_data *dev = fd->private_data; - struct usb_gadget *gadget = dev->gadget; + struct usb_gadget *gadget; long ret = -ENOTTY; spin_lock_irq(&dev->lock); + gadget = dev->gadget; if (dev->state == STATE_DEV_OPENED || dev->state == STATE_DEV_UNBOUND) { /* Not bound to a UDC */ |
