CVE-2026-80970: ALSA: FCP: do not copy out an uninitialised init response
In the Linux kernel, the following vulnerability has been resolved:
ALSA: FCP: do not copy out an uninitialised init response
fcpioctlinit() allocates its response buffer with kmalloc() and copies the whole buffer back to userspace:
bufsize = init.step0respsize + init.step2respsize;
void resp free(kfree) = kmalloc(bufsize, GFPKERNEL); ... if (copytouser(arg->resp, resp, bufsize)) return -EFAULT;
Nothing clears the buffer, and the only writer of its leading step0respsize bytes is the step-0 control transfer:
err = sndusbctlmsg(dev, usbrcvctrlpipe(dev, 0), FCPUSBREQSTEP0, USBRECIPINTERFACE | USBTYPECLASS | USBDIRIN, 0, private->bInterfaceNumber, step0resp, private->step0respsize); if (err < 0) return err;
usbfillcontrolurb() does not set URBSHORTNOTOK, so a short or zero-length data stage completes with status 0 and sndusbctlmsg() returns a small actuallength. The only check is err < 0, so a short transfer is accepted as success.
sndusbctlmsg() copies the full size back unconditionally:
buf = kmemdup(data, size, GFPKERNEL); ... memcpy(data, buf, size);
Bytes the device never wrote are therefore restored into resp unchanged and copied to userspace. step0respsize and step2respsize are each validated only to 1..255, so the caller also picks the slab cache, from kmalloc-8 up to kmalloc-512.
On 7.2.0-rc5 (arm64), device answering step 0 with a zero-length data stage, s0 = s2 = 255:
# initonalloc off, no spray step0 window [0,255): nonzero=94/255 000: 00 80 60 06 00 00 ff ff 18 00 00 00 57 01 ea 01 010: 08 78 22 13 00 00 ff ff a8 c4 5f 80 00 80 ff ff
# same kernel, kmalloc-512 pre-seeded with an 8-byte tag step0 window [0,255): nonzero=219/255 tagbytes=232
# identical run, initonalloc=1 step0 window [0,255): nonzero=0/255 tagbytes=0
# all three runs step2 window [255,510): device words matched=62/62
a8 c4 5f 80 00 80 ff ff is the little-endian kernel text address ffff8000805fc4a8. The step-2 window is unaffected, so the disclosure is exactly the step-0 region.
Zero the buffer, and require the step-0 transfer to deliver the full step0respsize bytes so a short data stage is reported as an error.
Discovered by XBOW, triaged by Baul Lee <baul.lee@xbow.com>
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Configuration
Apply the kernel fix described: zero the allocated response buffer and ensure the step-0 control transfer must deliver the full step-0 region (so a short step-0 data stage is rejected rather than returning a small actual_length while still copying full buf_size to userspace).
Linux kernel FCP ioctl path (fcp_ioctl_init / snd_usb_ctl_msg usage) Zero the response buffer before copying to userspace; require step-0 transfer to deliver full step-0 response size (use full-size transfer check; reject short transfer) = Implement buffer zeroing and strict full-length requirement for step-0 (ensure short data stage is treated as error)
Event History
Frequently Asked Questions
What condition causes data to be exposed?
The USB device must return a short or zero-length response during the step-0 control transfer while reporting successful completion. The code accepts this because it checks only for a negative error, not whether the full expected response length was received.
What is copied to userspace in the affected path?
Bytes in the allocated response buffer that the device did not write can remain uninitialized. The full buffer is then copied to the userspace response address.
Will a failed USB control transfer trigger the issue?
A control transfer returning a negative error is rejected. The issue arises when a transfer completes successfully with fewer bytes than requested, since that short result is treated as success.