ALSA: usbusx2y: validate URB actual_length in interrupt callback

i_usx2y_in04_int() processes the interrupt URB data without checking
urb->actual_length.  A short transfer from a malfunctioning device
would cause the handler to process uninitialized heap data from the
kmalloc-allocated in04_buf, which is then copied to the mmap-accessible
ctl_snapshot[] array.

Fix by using kzalloc() for in04_buf to zero-initialize the buffer,
and adding an actual_length check to skip processing on short
transfers while still resubmitting the URB.

Fixes: 1da177e4c3 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
Link: https://patch.msgid.link/20260904205826.4071119-2-tristmd@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
This commit is contained in:
Tristan Madani 2026-09-04 20:58:26 +00:00 committed by Takashi Iwai
parent 861111a147
commit 8f5ef203ab

View File

@ -189,6 +189,9 @@ static void i_usx2y_in04_int(struct urb *urb)
return;
}
if (urb->actual_length < USX2Y_IN04_SIZE)
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(USX2Y_IN04_SIZE, GFP_KERNEL);
usx2y->in04_buf = kzalloc(USX2Y_IN04_SIZE, GFP_KERNEL);
if (!usx2y->in04_buf) {
err = -ENOMEM;
goto error;