drivers/usb/serial/belkin_sa.c | 4 ++++ 1 file changed, 4 insertions(+)
The Belkin interrupt callback treats the interrupt packet as a four-byte
status report and reads LSR/MSR fields at offsets 2 and 3. The
interrupt-in buffer length is derived from endpoint wMaxPacketSize,
and short interrupt transfers may complete successfully with a smaller
actual_length.
Do not parse interrupt status unless both the URB buffer and the completed
packet are large enough for the status fields. This prevents devices with
short interrupt endpoints or short successful packets from driving
out-of-bounds or stale status-byte reads.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Zhang Cen <rollkingzzc@gmail.com>
---
drivers/usb/serial/belkin_sa.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c
index 38ac910b1082..a1e4173a2877 100644
--- a/drivers/usb/serial/belkin_sa.c
+++ b/drivers/usb/serial/belkin_sa.c
@@ -192,6 +192,10 @@ static void belkin_sa_read_int_callback(struct urb *urb)
goto exit;
}
+ if (urb->actual_length < BELKIN_SA_MSR_INDEX + 1 ||
+ urb->transfer_buffer_length < BELKIN_SA_MSR_INDEX + 1)
+ goto exit;
+
usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data);
/* Handle known interrupt data */
--
2.43.0
On Sat, May 16, 2026 at 12:24:28PM +0800, Zhang Cen wrote:
> The Belkin interrupt callback treats the interrupt packet as a four-byte
> status report and reads LSR/MSR fields at offsets 2 and 3. The
> interrupt-in buffer length is derived from endpoint wMaxPacketSize,
> and short interrupt transfers may complete successfully with a smaller
> actual_length.
>
> Do not parse interrupt status unless both the URB buffer and the completed
> packet are large enough for the status fields. This prevents devices with
> short interrupt endpoints or short successful packets from driving
> out-of-bounds or stale status-byte reads.
How was this issue found? Are you using some kind of static checker or
LLM?
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> Signed-off-by: Zhang Cen <rollkingzzc@gmail.com>
>
> ---
> drivers/usb/serial/belkin_sa.c | 4 ++++
> 1 file changed, 4 insertions(+)
>
> diff --git a/drivers/usb/serial/belkin_sa.c b/drivers/usb/serial/belkin_sa.c
> index 38ac910b1082..a1e4173a2877 100644
> --- a/drivers/usb/serial/belkin_sa.c
> +++ b/drivers/usb/serial/belkin_sa.c
> @@ -192,6 +192,10 @@ static void belkin_sa_read_int_callback(struct urb *urb)
> goto exit;
> }
>
> + if (urb->actual_length < BELKIN_SA_MSR_INDEX + 1 ||
> + urb->transfer_buffer_length < BELKIN_SA_MSR_INDEX + 1)
You only need to verify urb->actual_length here (as actual_length <=
transfer_buffer_length).
> + goto exit;
> +
> usb_serial_debug_data(&port->dev, __func__, urb->actual_length, data);
>
> /* Handle known interrupt data */
Johan
Hi Johan, Thanks for reviewing this. On Mon, May 18, 2026 at 01:07:05PM +0200, Johan Hovold wrote: > How was this issue found? Are you using some kind of static checker or > LLM? The initial lead came from an LLM-assisted local audit, not from a dedicated static checker. I then checked this path manually and validated the issue under KASAN with a small dummy_hcd/raw_gadget setup. The reproducer emulates a Belkin 050d:0103-compatible device with one interrupt-in endpoint whose wMaxPacketSize is 3. After belkin_sa bound and ttyUSB0 was opened once, the raw_gadget side completed 3-byte interrupt packets. The relevant part of the KASAN report as below: BUG: KASAN: slab-out-of-bounds in belkin_sa_read_int_callback+0xd3/0x290 Read of size 1 at addr ffff8881029d2c43 with the callback reached from URB completion: belkin_sa_read_int_callback+0xd3/0x290 __usb_hcd_giveback_urb+0x112/0x1d0 dummy_timer+0xaaa/0x19a0 __hrtimer_run_queues+0x102/0x510 hrtimer_run_softirq+0xd0/0x130 handle_softirqs+0x155/0x650 > You only need to verify urb->actual_length here (as actual_length <= > transfer_buffer_length). Agreed, thanks for pointing this out. I will send a v2 with the check reduced to: if (urb->actual_length < BELKIN_SA_MSR_INDEX + 1) goto exit; and update the commit message accordingly. Best regards, Zhang Cen
On Mon, May 18, 2026 at 09:39:49PM +0800, Cen Zhang wrote:
> On Mon, May 18, 2026 at 01:07:05PM +0200, Johan Hovold wrote:
>
> > How was this issue found? Are you using some kind of static checker or
> > LLM?
>
> The initial lead came from an LLM-assisted local audit, not from a
> dedicated static checker. I then checked this path manually and validated
> the issue under KASAN with a small dummy_hcd/raw_gadget setup.
>
> The reproducer emulates a Belkin 050d:0103-compatible device with one
> interrupt-in endpoint whose wMaxPacketSize is 3. After belkin_sa bound and
> ttyUSB0 was opened once, the raw_gadget side completed 3-byte interrupt
> packets.
>
> The relevant part of the KASAN report as below:
>
> BUG: KASAN: slab-out-of-bounds in belkin_sa_read_int_callback+0xd3/0x290
> Read of size 1 at addr ffff8881029d2c43
Nice work. But please mention that this found with the help of an LLM in
the commit message as documented in:
- Documentation/process/submitting-patches.rst ("Using Assisted-by:")
- Documentation/process/coding-assistants.rst
> > You only need to verify urb->actual_length here (as actual_length <=
> > transfer_buffer_length).
>
> Agreed, thanks for pointing this out. I will send a v2 with the check
> reduced to:
>
> if (urb->actual_length < BELKIN_SA_MSR_INDEX + 1)
> goto exit;
>
> and update the commit message accordingly.
Sounds good, thanks.
Johan
Hi Johan,
Thanks for your guidence.
Johan Hovold <johan@kernel.org> 于2026年5月18日周一 22:38写道:
>
> Nice work. But please mention that this found with the help of an LLM in
> the commit message as documented in:
>
> - Documentation/process/submitting-patches.rst ("Using Assisted-by:")
> - Documentation/process/coding-assistants.rst
I will add an Assisted-by trailer in v2 and also use the Assisted-by trailer for
future kernel patches where an LLM materially helped find or develop the fix,
following the documented process.
Best regards,
Zhang Cen
© 2016 - 2026 Red Hat, Inc.