A KASAN slab-use-after-free can occur in gadget_dev_open() due to an unbalanced reference count in the error path of gadgetfs_bind(). When gadgetfs_bind() is called, it performs several initialization steps. If it succeeds, it takes a reference to the dev object by calling get_dev(dev) at the very end of the function. This reference is meant to be balanced by a call to put_dev(dev) inside gadgetfs_unbind() when the driver is eventually unbound. However, if gadgetfs_bind() fails midway (e.g., due to a memory allocation failure in usb_ep_alloc_request() or activate_ep_files()), it jumps to the enomem label and calls gadgetfs_unbind(gadget). Because get_dev(dev) was never called, gadgetfs_unbind() drops a reference that was never acquired. This leads to the dev object being freed prematurely when the file descriptor is closed, resulting in a use-after-free when the file is opened again. BUG: KASAN: slab-use-after-free in __raw_spin_lock_irq include/linux/spinlock_api_smp.h:142 [inline] BUG: KASAN: slab-use-after-free in _raw_spin_lock_irq+0x58/0x70 kernel/locking/spinlock.c:174 Read of size 1 at addr ffff0000dbe16018 by task syz.0.18/5334 ... Call trace: ... __raw_spin_lock_irq include/linux/spinlock_api_smp.h:142 [inline] _raw_spin_lock_irq+0x58/0x70 kernel/locking/spinlock.c:174 spin_lock_irq include/linux/spinlock.h:372 [inline] gadget_dev_open+0x50/0x1c4 drivers/usb/gadget/legacy/inode.c:1919 do_dentry_open+0x5c4/0xfc0 fs/open.c:947 vfs_open+0x44/0x2dc fs/open.c:1052 To fix this, replace the monolithic gadgetfs_unbind() call in the enomem error path with manual, step-by-step cleanup of exactly the resources that were allocated prior to the failure. If dev->req was allocated, it is freed and set to NULL. The gadget data pointers (gadget->ep0->driver_data, dev->gadget, and set_gadget_data) are cleared. Note that activate_ep_files() already cleans up after itself if it fails, so we don't need to manually undo its effects. This ensures that only the resources actually allocated by gadgetfs_bind() are cleaned up, preventing the unbalanced put_dev() and incorrect state changes that caused the use-after-free. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Assisted-by: Gemini:gemini-3.5-flash Gemini:gemini-3.1-pro-preview syzbot Reported-by: syzbot+1459655b2bf1e798f9d0@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=1459655b2bf1e798f9d0 Link: https://syzkaller.appspot.com/ai_job?id=992d95f0-8de6-44af-9ebe-f7c976f4ba68 To: "Greg Kroah-Hartman" To: To: "Linus Torvalds" Cc: "Christian Brauner" Cc: "Jan Kara" Cc: "Kees Cook" Cc: Cc: "Mateusz Guzik" Cc: "Al Viro" --- diff --git a/drivers/usb/gadget/legacy/inode.c b/drivers/usb/gadget/legacy/inode.c index d87a8ab51..365f9ab4d 100644 --- a/drivers/usb/gadget/legacy/inode.c +++ b/drivers/usb/gadget/legacy/inode.c @@ -1700,7 +1700,13 @@ static int gadgetfs_bind(struct usb_gadget *gadget, return 0; enomem: - gadgetfs_unbind (gadget); + if (dev->req) { + usb_ep_free_request(gadget->ep0, dev->req); + dev->req = NULL; + } + gadget->ep0->driver_data = NULL; + dev->gadget = NULL; + set_gadget_data(gadget, NULL); return -ENOMEM; } base-commit: f5098b6bae761e346ebcd9da7f95622c04733cff -- This is an AI-generated patch subject to moderation. Reply with '#syz upstream' to Sign-off the patch as a human author and send it to the upstream kernel mailing lists. Reply with '#syz reject' to reject it ('#syz unreject' to undo). See https://goo.gle/syzbot-ai-patches for information about AI-generated patches. You can comment on the patch as usual, syzbot will try to address the comments and send a new version of the patch if necessary. syzbot engineers can be reached at syzkaller@googlegroups.com.