Re: [syzbot] [usb?] BUG: corrupted list in usb_hcd_link_urb_to_ep (5)

From: Alan Stern

Date: Wed Jul 08 2026 - 10:38:26 EST


On Sun, Jul 05, 2026 at 03:23:29AM -0700, syzbot wrote:
> syzbot has found a reproducer for the following issue on:
>
> HEAD commit: 2b763db0c276 Add linux-next specific files for 20260703
> git tree: linux-next
> console output: https://syzkaller.appspot.com/x/log.txt?x=11f96ffe580000
> kernel config: https://syzkaller.appspot.com/x/.config?x=bc069df559a09463
> dashboard link: https://syzkaller.appspot.com/bug?extid=e69c25cf38a53d0cf64c
> compiler: Debian clang version 22.1.8 (++20260613092233+e80beda6e255-1~exp1~20260613092250.77), Debian LLD 22.1.8
> syz repro: https://syzkaller.appspot.com/x/repro.syz?x=14a9dffe580000
> C reproducer: https://syzkaller.appspot.com/x/repro.c?x=103d8b1c580000

Second try for this patch. Maybe the current -rc will work better
than linux-next.

Alan Stern

#syz test: upstream v7.2-rc2

Index: usb-devel/drivers/input/misc/cm109.c
===================================================================
--- usb-devel.orig/drivers/input/misc/cm109.c
+++ usb-devel/drivers/input/misc/cm109.c
@@ -349,10 +349,14 @@ static void cm109_submit_buzz_toggle(str
dev->ctl_data->byte[HID_OR0] &= ~BUZZER_ON;

error = usb_submit_urb(dev->urb_ctl, GFP_ATOMIC);
- if (error)
+ if (error) {
dev_err(&dev->intf->dev,
"%s: usb_submit_urb (urb_ctl) failed %d\n",
__func__, error);
+ } else {
+ dev->ctl_urb_pending = 1;
+ dev->buzzer_pending = 0;
+ }
}

static void cm109_submit_ctl(struct cm109_dev *dev)
@@ -361,9 +365,7 @@ static void cm109_submit_ctl(struct cm10

guard(spinlock_irqsave)(&dev->ctl_submit_lock);

- dev->irq_urb_pending = 0;
-
- if (unlikely(dev->shutdown))
+ if (unlikely(dev->shutdown) || dev->ctl_urb_pending)
return;

if (dev->buzzer_state)
@@ -374,14 +376,15 @@ static void cm109_submit_ctl(struct cm10
dev->ctl_data->byte[HID_OR1] = dev->keybit;
dev->ctl_data->byte[HID_OR2] = dev->keybit;

- dev->buzzer_pending = 0;
- dev->ctl_urb_pending = 1;
-
error = usb_submit_urb(dev->urb_ctl, GFP_ATOMIC);
- if (error)
+ if (error) {
dev_err(&dev->intf->dev,
"%s: usb_submit_urb (urb_ctl) failed %d\n",
__func__, error);
+ } else {
+ dev->ctl_urb_pending = 1;
+ dev->buzzer_pending = 0;
+ }
}

/*
@@ -428,6 +431,7 @@ static void cm109_urb_irq_callback(struc
}

out:
+ dev->irq_urb_pending = 0;
cm109_submit_ctl(dev);
}

@@ -458,17 +462,16 @@ static void cm109_urb_ctl_callback(struc
return;

if (dev->buzzer_pending || status) {
- dev->buzzer_pending = 0;
- dev->ctl_urb_pending = 1;
cm109_submit_buzz_toggle(dev);
} else if (likely(!dev->irq_urb_pending)) {
/* ask for key data */
- dev->irq_urb_pending = 1;
error = usb_submit_urb(dev->urb_irq, GFP_ATOMIC);
if (error)
dev_err(&dev->intf->dev,
"%s: usb_submit_urb (urb_irq) failed %d\n",
__func__, error);
+ else
+ dev->irq_urb_pending = 1;
}
}

@@ -480,7 +483,6 @@ static void cm109_toggle_buzzer_async(st
/* URB completion will resubmit */
dev->buzzer_pending = 1;
} else {
- dev->ctl_urb_pending = 1;
cm109_submit_buzz_toggle(dev);
}
}