heap-buffer-overflow in esp_do_dma()
Host environment
-
Operating system: Ubuntu 20.04
-
OS/kernel version: Linux 5.4.0-148
-
Architecture: x86_64
-
QEMU flavor: qemu-system-x86_64
-
QEMU version: commit at c167c80b
-
QEMU command line:
QEMU_FUZZ_ARGS="-device am53c974,id=scsi -device scsi-hd,drive=disk0 -drive id=disk0,if=none,file=null-co://,format=raw -nodefaults" \ QEMU_FUZZ_OBJECTS="*esp* *scsi* *am53c974*" ./qemu-fuzz-x86_64 --fuzz-target=generic-fuzz
Description of problem
Got a heap-buffer-overflow error when fuzzing the device am53c974.
Steps to reproduce
Minimized reproducer:
cat << EOF | ./qemu-system-x86_64 -display none -machine accel=qtest, -m 512M -device \
am53c974,id=scsi -device scsi-hd,drive=disk0 -drive \
id=disk0,if=none,file=null-co://,format=raw -nodefaults -qtest /dev/null\
-qtest stdio
outl 0xcf8 0x80001010
outl 0xcfc 0xc000
outl 0xcf8 0x80001004
outw 0xcfc 0x05
outl 0xc03d 0x03000000
outl 0xc047 0x065a9d80
outl 0xc00a 0xc10000
write 0x65a9d 0x1 0x04
write 0x65a9e 0x1 0x10
outl 0xc03d 0x03000000
outl 0xc00a 0xc10000
outl 0xc00b 0x0800
outl 0xc00b 0x00
outl 0xc00b 0x0800
outl 0xc00b 0x0800
outl 0xc00b 0x0800
outl 0xc00b 0x0400
outl 0xc00b 0x0800
outl 0xc00b 0x0800
outw 0xc00b 0x1000
outw 0xc00b 0x9000
EOF
Additional information
The crash report triggered by the reproducer is:
[I 0.000000] OPENED
[R +0.022834] outl 0xcf8 0x80001010
[S +0.022864] OK
OK
[R +0.022874] outl 0xcfc 0xc000
[S +0.022887] OK
OK
[R +0.022942] outl 0xcf8 0x80001004
[S +0.022990] OK
OK
[R +0.023028] outw 0xcfc 0x05
[S +0.023508] OK
OK
[R +0.023518] outl 0xc03d 0x03000000
[S +0.023527] OK
OK
[R +0.023532] outl 0xc047 0x065a9d80
[S +0.023537] OK
OK
[R +0.023544] outl 0xc00a 0xc10000
[S +0.023573] OK
OK
[R +0.023581] write 0x65a9d 0x1 0x04
[S +0.023891] OK
OK
[R +0.023900] write 0x65a9e 0x1 0x10
[S +0.023906] OK
OK [R +0.023910] outl 0xc03d 0x03000000
[S +0.023917] OK
OK
[R +0.023921] outl 0xc00a 0xc10000
[S +0.023983] OK
OK
[R +0.023581] write 0x65a9d 0x1 0x04
[S +0.023891] OK
OK
[R +0.023900] write 0x65a9e 0x1 0x10
[S +0.023906] OK
OK [R +0.023910] outl 0xc03d 0x03000000
[S +0.023917] OK
OK
[R +0.023921] outl 0xc00a 0xc10000
[S +0.023983] OK
OK
[R +0.023991] outl 0xc00b 0x0800
[S +0.023998] OK
OK
[R +0.024002] outl 0xc00b 0x00
[S +0.024008] OK
OK
[R +0.024014] outl 0xc00b 0x0800
[S +0.024028] OK
OK
[R +0.024034] outl 0xc00b 0x0800
[S +0.024040] OK
OK
[R +0.024051] outl 0xc00b 0x0800
[S +0.024058] OK
OK
[R +0.024065] outl 0xc00b 0x0400
[S +0.024073] OK
OK
[R +0.024082] outl 0xc00b 0x0800
[S +0.024089] OK
OK
[R +0.024104] outl 0xc00b 0x0800
[S +0.024121] OK
OK
[R +0.024133] outw 0xc00b 0x1000
[S +0.024150] OK
OK
[R +0.024159] outw 0xc00b 0x9000
=================================================================
==63330==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x62500020c000 at pc 0x5601fffcf1d4 bp 0x7ffe1920dcf0 sp 0x7ffe1920d4b0
WRITE of size 32736 at 0x62500020c000 thread T0
#0 0x5601fffcf1d3 in __asan_memcpy ../../llvm-project-15.0.0.src/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:22:3
#1 0x5602015f506b in flatview_read_continue ../softmmu/physmem.c:2726:13
#2 0x5602015f5ee3 in flatview_read ../softmmu/physmem.c:2762:12
#3 0x5602015f5bf7 in address_space_read_full ../softmmu/physmem.c:2775:18
#4 0x560200943ef0 in dma_memory_rw_relaxed ../include/sysemu/dma.h:87:12
#5 0x560200943ef0 in dma_memory_rw ../include/sysemu/dma.h:130:12
#6 0x560200943ef0 in pci_dma_rw ../hw/pci/pci_device.h:233:12
#7 0x560200943ef0 in esp_pci_dma_memory_rw ../hw/scsi/esp-pci.c:283:5
#8 0x56020092db7e in esp_do_dma ../hw/scsi/esp.c
#9 0x560200935774 in handle_ti ../hw/scsi/esp.c:912:9
#10 0x560200932db6 in esp_reg_write ../hw/scsi/esp.c:1083:13
#11 0x56020094574d in esp_pci_io_write ../hw/scsi/esp-pci.c:214:9
#12 0x5602015b5f23 in memory_region_write_accessor ../softmmu/memory.c:493:5
#13 0x5602015b56aa in access_with_adjusted_size ../softmmu/memory.c:569:18
#14 0x5602015b4a50 in memory_region_dispatch_write ../softmmu/memory.c
#15 0x5602015fefbf in flatview_write_continue ../softmmu/physmem.c:2653:23
#16 0x5602015f6463 in flatview_write ../softmmu/physmem.c:2695:12
#17 0x5602015f6177 in address_space_write ../softmmu/physmem.c:2791:18
#18 0x5602015a7e99 in cpu_outw ../softmmu/ioport.c:75:5
#19 0x560200d28daa in qtest_process_command ../softmmu/qtest.c:483:13
#20 0x560200d2795b in qtest_process_inbuf ../softmmu/qtest.c:788:9
#21 0x560201b581a6 in fd_chr_read ../chardev/char-fd.c:72:9
#22 0x7f8fce57e04d in g_main_context_dispatch (/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x5204d) (BuildId: 5fdb313daf182a33a858ba2cc945211b11d34561)
#23 0x560201dc540f in glib_pollfds_poll ../util/main-loop.c:290:9
#24 0x560201dc540f in os_host_main_loop_wait ../util/main-loop.c:313:5
#25 0x560201dc540f in main_loop_wait ../util/main-loop.c:592:11
#26 0x560200d34f76 in qemu_main_loop ../softmmu/runstate.c:732:9
#27 0x56020173e835 in qemu_default_main ../softmmu/main.c:37:14
#28 0x7f8fcd3a5082 in __libc_start_main /build/glibc-SzIz7B/glibc-2.31/csu/../csu/libc-start.c:308:16
#29 0x5601fff2009d in _start ./qemu-system-x86_64+0x1e9109d)
0x62500020c000 is located 0 bytes to the right of 4096-byte region [0x62500020b000,0x62500020c000)
allocated by thread T0 here:
#0 0x5601fffd0a0c in posix_memalign ../../llvm-project-15.0.0.src/compiler-rt/lib/asan/asan_malloc_linux.cpp:145:3
#1 0x560201db83da in qemu_try_memalign ../util/memalign.c:53:11
#2 0x560201db8762 in qemu_memalign ../util/memalign.c:73:15
#3 0x5602008c779e in scsi_req_enqueue ../hw/scsi/scsi-bus.c:906:10
#4 0x56020093bd2f in do_command_phase ../hw/scsi/esp.c:296:15
#5 0x56020093bd2f in do_cmd ../hw/scsi/esp.c:344:5
#6 0x560200932911 in esp_reg_write ../hw/scsi/esp.c:1112:13
#7 0x56020094574d in esp_pci_io_write ../hw/scsi/esp-pci.c:214:9
#8 0x5602015b5f23 in memory_region_write_accessor ../softmmu/memory.c:493:5
#9 0x5602015b56aa in access_with_adjusted_size ../softmmu/memory.c:569:18
SUMMARY: AddressSanitizer: heap-buffer-overflow ./llvm-project-15.0.0.src/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cpp:22:3 in __asan_memcpy
Shadow bytes around the buggy address:
0x0c4a800397b0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c4a800397c0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c4a800397d0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c4a800397e0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c4a800397f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c4a80039800:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c4a80039810: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c4a80039820: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c4a80039830: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c4a80039840: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c4a80039850: 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
==63330==ABORTING