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>