A KASAN slab-use-after-free bug was found in gadgetfs_kill_sb(): BUG: KASAN: slab-use-after-free in put_dev drivers/usb/gadget/legacy/inode.c:165 [inline] BUG: KASAN: slab-use-after-free in gadgetfs_kill_sb+0x46/0x110 drivers/usb/gadget/legacy/inode.c:2104 Write of size 4 at addr ffff88811638c080 by task syz-executor169/5848 CPU: 0 UID: 0 PID: 5848 Comm: syz-executor169 Not tainted Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 Call Trace: dump_stack_lvl+0xe8/0x150 lib/dump_stack.c:120 print_address_description+0x55/0x1e0 mm/kasan/report.c:378 print_report+0x58/0x70 mm/kasan/report.c:482 kasan_report+0x117/0x150 mm/kasan/report.c:595 check_region_inline mm/kasan/generic.c:-1 [inline] kasan_check_range+0x264/0x2c0 mm/kasan/generic.c:200 instrument_atomic_read_write include/linux/instrumented.h:112 [inline] atomic_fetch_sub_release include/linux/atomic/atomic-instrumented.h:400 [inline] __refcount_sub_and_test include/linux/refcount.h:389 [inline] __refcount_dec_and_test include/linux/refcount.h:432 [inline] refcount_dec_and_test include/linux/refcount.h:450 [inline] put_dev drivers/usb/gadget/legacy/inode.c:165 [inline] gadgetfs_kill_sb+0x46/0x110 drivers/usb/gadget/legacy/inode.c:2104 deactivate_locked_super+0xbc/0x130 fs/super.c:477 cleanup_mnt+0x3d3/0x460 fs/namespace.c:1317 task_work_run+0x1d9/0x270 kernel/task_work.c:233 The root cause is a reference count underflow in the error handling path of gadgetfs_bind(). When gadgetfs_bind() encounters an error (e.g., memory allocation failure), it jumps to the enomem label and calls gadgetfs_unbind(). However, gadgetfs_unbind() is designed to tear down a fully initialized and bound gadget, and unconditionally drops a device reference by calling put_dev(dev). Since gadgetfs_bind() only acquires this reference (get_dev(dev)) at the very end of the function upon complete success, calling gadgetfs_unbind() in the error path drops a reference that was never taken. This leads to a premature free of the dev structure when the ep0 file is closed, and subsequently a use-after-free when the filesystem is unmounted and gadgetfs_kill_sb() tries to drop the initial reference. To fix this, stop calling the full teardown function gadgetfs_unbind() from the gadgetfs_bind() error path. Instead, manually and locally clean up only the specific state that was successfully altered before the failure occurred. Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Assisted-by: Gemini:gemini-3.5-flash Gemini:gemini-3.1-pro-preview syzbot Reported-by: syzbot+4a5c87a01894ca37f25c@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=4a5c87a01894ca37f25c Link: https://syzkaller.appspot.com/ai_job?id=d40043f8-d813-4477-b6e2-0f071c04be7c 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: 075b74841bd0065a3bda3440873c747938e69b68 -- 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. The person who has signed off on the patch is responsible for addressing comments. syzbot engineers can be reached at syzkaller@googlegroups.com.