[PATCH 2/2] ALSA: usbusx2y: validate URB actual_length in interrupt callback

From: Tristan Madani

Date: Fri Sep 04 2026 - 06:10:45 EST


From: Tristan Madani <tristan@xxxxxxxxxxxxxxxxxxx>

i_usx2y_in04_int() processes the interrupt URB data without checking
urb->actual_length. A malfunctioning USB device could send a short
transfer, causing the handler to process uninitialized heap data from
the kmalloc-allocated in04_buf.

This is problematic because in04_buf is allocated with kmalloc() (not
kzalloc()), so uninitialized slab data may be present before the first
full transfer. The data is then copied to us428ctls->ctl_snapshot[],
which is mmap-accessible to userspace via snd_us428ctls_mmap().

Fix by:
1. Using kzalloc() for in04_buf to zero-initialize the buffer
2. Adding an actual_length check at the start of the callback to skip
processing on short transfers while still resubmitting the URB

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Tristan Madani <tristan@xxxxxxxxxxxxxxxxxxx>
---
sound/usb/usx2y/usbusx2y.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/sound/usb/usx2y/usbusx2y.c b/sound/usb/usx2y/usbusx2y.c
index 4190227c5a2a5..5744a873aac26 100644
--- a/sound/usb/usx2y/usbusx2y.c
+++ b/sound/usb/usx2y/usbusx2y.c
@@ -189,6 +189,9 @@ static void i_usx2y_in04_int(struct urb *urb)
return;
}

+ if (urb->actual_length < 21)
+ goto resubmit;
+
if (us428ctls) {
diff = -1;
if (us428ctls->ctl_snapshot_last == -2) {
@@ -253,6 +256,7 @@ static void i_usx2y_in04_int(struct urb *urb)
if (err)
dev_err(&urb->dev->dev, "in04_int() usb_submit_urb err=%i\n", err);

+resubmit:
urb->dev = usx2y->dev;
usb_submit_urb(urb, GFP_ATOMIC);
}
@@ -305,7 +309,7 @@ int usx2y_in04_init(struct usx2ydev *usx2y)
goto error;
}

- usx2y->in04_buf = kmalloc(21, GFP_KERNEL);
+ usx2y->in04_buf = kzalloc(21, GFP_KERNEL);
if (!usx2y->in04_buf) {
err = -ENOMEM;
goto error;
--
2.47.3