Heap-use-after-free through ehci_flush_qh
This was originally reported at: https://bugs.launchpad.net/qemu/+bug/1892963
Hello,
Reproducer
cat << EOF | ./qemu-system-i386 -machine q35 -device \
ich9-usb-ehci1,bus=pcie.0,addr=1d.7,multifunction=on,id=ich9-ehci-1 \
-drive if=none,id=usbcdrom,media=cdrom -device \
usb-storage,bus=ich9-ehci-1.0,port=2,drive=usbcdrom -display none \
-nodefaults -qtest stdio -accel qtest
outl 0xcf8 0x8000ef02
outl 0xcfc 0xfbff0061
outl 0xcf8 0x8000ef11
outl 0xcfc 0x60606060
writeq 0x60606065 0xb70560ff84ffff7f
writeq 0x60606065 0xff0004fe050000ff
writeq 0x60606020 0xff015e5c057b0039
writeq 0x60606033 0x846c8a0200000611
write 0x2000004 0x4 0x4a606060
write 0x8 0x4 0x97a98095
write 0x0 0x4 0x4a606060
write 0x4 0x4 0x97a98095
write 0xc 0x4 0x4a606060
write 0x10 0x4 0x97a98095
write 0x14 0x4 0x4a606060
write 0x18 0x4 0x97a98095
write 0x1c 0x4 0x4a606060
clock_step
EOF
Stack-Trace
=================================================================
==213636==ERROR: AddressSanitizer: heap-use-after-free on address 0x611000059e28 at pc 0x557245330ff7 bp 0x7ffc14f3fec0 sp 0x7ffc14f3feb8
READ of size 4 at 0x611000059e28 thread T0
#0 0x557245330ff6 in usb_packet_unmap ../hw/usb/libhw.c:64:28
#1 0x55724533078b in usb_packet_map ../hw/usb/libhw.c:54:5
#2 0x5572450be79e in ehci_execute ../hw/usb/hcd-ehci.c:1375:13
#3 0x5572450b30de in ehci_state_execute ../hw/usb/hcd-ehci.c:1949:13
#4 0x5572450b30de in ehci_advance_state ../hw/usb/hcd-ehci.c:2090:21
#5 0x55724509785c in ehci_advance_periodic_state ../hw/usb/hcd-ehci.c:2220:9
#6 0x55724509785c in ehci_work_bh ../hw/usb/hcd-ehci.c:2306:17
#7 0x5572469b5832 in aio_bh_poll ../util/async.c:169:13
#8 0x557246a3770b in aio_dispatch ../util/aio-posix.c:381:5
#9 0x5572469b93ea in aio_ctx_dispatch ../util/async.c:311:5
#10 0x7fca55407e6a in g_main_context_dispatch (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x51e6a)
#11 0x557246976053 in glib_pollfds_poll ../util/main-loop.c:232:9
#12 0x557246976053 in os_host_main_loop_wait ../util/main-loop.c:255:5
#13 0x557246976053 in main_loop_wait ../util/main-loop.c:531:11
#14 0x557245fe10c6 in qemu_main_loop ../softmmu/runstate.c:726:9
#15 0x557244b4f85a in main ../softmmu/main.c:50:5
#16 0x7fca53b66d09 in __libc_start_main csu/../csu/libc-start.c:308:16
#17 0x557244aa3259 in _start (system-i386+0x2204259)
0x611000059e28 is located 104 bytes inside of 248-byte region [0x611000059dc0,0x611000059eb8)
freed by thread T0 here:
#0 0x557244b1d04d in free (system-i386+0x227e04d)
#1 0x55724509d5f0 in ehci_free_packet ../hw/usb/hcd-ehci.c:540:5
#2 0x55724509c197 in ehci_cancel_queue ../hw/usb/hcd-ehci.c:583:9
#3 0x55724509b266 in ehci_free_queue ../hw/usb/hcd-ehci.c:610:17
#4 0x5572450ae0e0 in ehci_queues_rip_device ../hw/usb/hcd-ehci.c:673:9
#5 0x5572450aafa7 in ehci_detach ../hw/usb/hcd-ehci.c:731:5
#6 0x557244da10fa in usb_detach ../hw/usb/core.c:70:5
#7 0x557244da138f in usb_port_reset ../hw/usb/core.c:79:5
#8 0x5572450c3533 in ehci_port_write ../hw/usb/hcd-ehci.c:992:13
#9 0x5572460dbf75 in memory_region_write_accessor ../softmmu/memory.c:492:5
#10 0x5572460dba9a in access_with_adjusted_size ../softmmu/memory.c:554:18
previously allocated by thread T0 here:
#0 0x557244b1d442 in calloc (system-i386+0x227e442)
#1 0x7fca5540dda0 in g_malloc0 (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x57da0)
#2 0x5572450b4a7c in ehci_state_fetchqtd ../hw/usb/hcd-ehci.c:1851:13
#3 0x5572450b4a7c in ehci_advance_state ../hw/usb/hcd-ehci.c:2080:21
#4 0x55724509785c in ehci_advance_periodic_state ../hw/usb/hcd-ehci.c:2220:9
#5 0x55724509785c in ehci_work_bh ../hw/usb/hcd-ehci.c:2306:17
#6 0x5572469b5832 in aio_bh_poll ../util/async.c:169:13
#7 0x557246a3770b in aio_dispatch ../util/aio-posix.c:381:5
SUMMARY: AddressSanitizer: heap-use-after-free ../hw/usb/libhw.c:64:28 in usb_packet_unmap
Shadow bytes around the buggy address:
0x0c2280003370: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c2280003380: fd fd fd fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c2280003390: fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd fd
0x0c22800033a0: fd fd fd fd fd fd fd fd fd fd fd fa fa fa fa fa
0x0c22800033b0: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
=>0x0c22800033c0: fd fd fd fd fd[fd]fd fd fd fd fd fd fd fd fd fd
0x0c22800033d0: fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa fa
0x0c22800033e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c22800033f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c2280003400: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c2280003410: 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
==213636==ABORTING
OSS-Fuzz Report: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=1892963
libqtest Reproducer: 1892963.c
Thank you
Edited by Alexander Bulekov