Heap-use-after-free in usb_packet_unmap through xhci
This was originally reported at: https://bugs.launchpad.net/qemu/+bug/1891354
Hello,
Reproducer
cat << EOF | ./qemu-system-i386 -device nec-usb-xhci -trace usb\* \
-device usb-audio -device usb-storage,drive=mydrive -drive \
id=mydrive,file=null-co://,size=2M,format=raw,if=none -nodefaults \
-nographic -qtest stdio
outl 0xcf8 0x80001010
outl 0xcfc 0xc0202
outl 0xcf8 0x80001004
outl 0xcfc 0x1c77695e
writel 0xc0040 0xffffd855
writeq 0xc2000 0xff05140100000000
write 0x1d 0x1 0x27
write 0x2d 0x1 0x2e
write 0x17232 0x1 0x03
write 0x17254 0x1 0x05
write 0x17276 0x1 0x72
write 0x17278 0x1 0x02
write 0x3d 0x1 0x27
write 0x40 0x1 0x2e
write 0x41 0x1 0x72
write 0x42 0x1 0x01
write 0x4d 0x1 0x2e
write 0x4f 0x1 0x01
write 0x2007c 0x1 0xc7
writeq 0xc2000 0x5c05140100000000
write 0x20070 0x1 0x80
write 0x20078 0x1 0x08
write 0x2007c 0x1 0xfe
write 0x2007d 0x1 0x08
write 0x20081 0x1 0xff
write 0x20082 0x1 0x0b
write 0x20089 0x1 0x8c
write 0x2008d 0x1 0x04
write 0x2009d 0x1 0x10
writeq 0xc2000 0x2505ef019e092f00
EOF
Stack-Trace
==206134==ERROR: AddressSanitizer: heap-use-after-free on address 0x611000069f70 at pc 0x563573ed9ff7 bp 0x7ffef4510320 sp 0x7ffef4510318
READ of size 4 at 0x611000069f70 thread T0
#0 0x563573ed9ff6 in usb_packet_unmap ../hw/usb/libhw.c:64:28
#1 0x563573ed978b in usb_packet_map ../hw/usb/libhw.c:54:5
#2 0x563573ac7387 in xhci_setup_packet ../hw/usb/hcd-xhci.c:1571:9
#3 0x563573ac0fec in xhci_fire_ctl_transfer ../hw/usb/hcd-xhci.c:1678:9
#4 0x563573ac0fec in xhci_kick_epctx ../hw/usb/hcd-xhci.c:1949:13
#5 0x563573ae4909 in xhci_doorbell_write ../hw/usb/hcd-xhci.c:3118:13
#6 0x563574c84f75 in memory_region_write_accessor ../softmmu/memory.c:492:5
#7 0x563574c84a9a in access_with_adjusted_size ../softmmu/memory.c:554:18
#8 0x563574c8455f in memory_region_dispatch_write ../softmmu/memory.c
#9 0x563574deae26 in flatview_write_continue ../softmmu/physmem.c:2777:23
#10 0x563574de2995 in flatview_write ../softmmu/physmem.c:2817:14
#11 0x563574de2995 in address_space_write ../softmmu/physmem.c:2909:18
#12 0x563574d1b167 in qtest_process_command ../softmmu/qtest.c:555:13
#13 0x563574d18b58 in qtest_process_inbuf ../softmmu/qtest.c:813:9
#14 0x563574ebfe14 in fd_chr_read ../chardev/char-fd.c:73:9
#15 0x7f8f60548d6e in g_main_context_dispatch (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x51d6e)
#16 0x56357551f053 in glib_pollfds_poll ../util/main-loop.c:232:9
#17 0x56357551f053 in os_host_main_loop_wait ../util/main-loop.c:255:5
#18 0x56357551f053 in main_loop_wait ../util/main-loop.c:531:11
#19 0x563574b8a0c6 in qemu_main_loop ../softmmu/runstate.c:726:9
#20 0x5635736f885a in main ../softmmu/main.c:50:5
#21 0x7f8f5eca7d09 in __libc_start_main csu/../csu/libc-start.c:308:16
#22 0x56357364c259 in _start (system-i386+0x2204259)
0x611000069f70 is located 48 bytes inside of 256-byte region [0x611000069f40,0x61100006a040)
freed by thread T0 here:
#0 0x5635736c604d in free (system-i386+0x227e04d)
#1 0x563573adc0d0 in xhci_ep_nuke_xfers ../hw/usb/hcd-xhci.c:1205:9
#2 0x563573aefe31 in xhci_disable_ep ../hw/usb/hcd-xhci.c:1232:5
#3 0x563573aef06d in xhci_disable_slot ../hw/usb/hcd-xhci.c:2006:13
#4 0x563573ad68d9 in xhci_reset ../hw/usb/hcd-xhci.c:2664:9
#5 0x563573adfb0a in xhci_oper_write ../hw/usb/hcd-xhci.c:2922:13
#6 0x563574c84f75 in memory_region_write_accessor ../softmmu/memory.c:492:5
#7 0x563574c84a9a in access_with_adjusted_size ../softmmu/memory.c:554:18
previously allocated by thread T0 here:
#0 0x5635736c6442 in calloc (system-i386+0x227e442)
#1 0x7f8f6054eda0 in g_malloc0 (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x57da0)
#2 0x563573ae4909 in xhci_doorbell_write ../hw/usb/hcd-xhci.c:3118:13
#3 0x563574c84f75 in memory_region_write_accessor ../softmmu/memory.c:492:5
#4 0x563574c84a9a in access_with_adjusted_size ../softmmu/memory.c:554:18
SUMMARY: AddressSanitizer: heap-use-after-free ../hw/usb/libhw.c:64:28 in usb_packet_unmap
Shadow bytes around the buggy address:
0x0c2280005390: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
0x0c22800053a0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c22800053b0: fd fd fd fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c22800053c0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c22800053d0: fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa fa
=>0x0c22800053e0: fa fa fa fa fa fa fa fa fd fd fd fd fd fd[fd]fd
0x0c22800053f0: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c2280005400: fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa
0x0c2280005410: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c2280005420: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c2280005430: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
Addressable: 00
Partially addressable: 01 02 03 04 05 06 07
Heap left redzone: fa
Freed heap region: fd
Stack left redzone: f1
Stack mid redzone: f2
Stack right redzone: f3
Stack after return: f5
Stack use after scope: f8
Global redzone: f9
Global init order: f6
Poisoned by user: f7
Container overflow: fc
Array cookie: ac
Intra object redzone: bb
ASan internal: fe
Left alloca redzone: ca
Right alloca redzone: cb
Shadow gap: cc
==206134==ABORTING
OSS-Fuzz Report: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1891354
libqtest Reproducer: 1891354.c
Thank you