UFS Device sanitizers error
Description of problem
Sanitizers error reported by Zheyu Ma zheyuma97@gmail.com
The following log can reveal it:
==3619819==ERROR: AddressSanitizer: heap-buffer-overflow on address
0x62a000011200 at pc 0x7f9f9903a2c3 bp 0x7ffd44e1ee60 sp 0x7ffd44e1e608
WRITE of size 20512 at 0x62a000011200 thread T0
#0 0x7f9f9903a2c2 in __interceptor_memcpy
../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:827
#1 0x5f23331ea4fc in memcpy
/usr/include/x86_64-linux-gnu/bits/string_fortified.h:29
#2 0x5f23331ea4fc in flatview_read_continue_step
../system/physmem.c:2818
#3 0x5f23331eab72 in flatview_read_continue ../system/physmem.c:2835
#4 0x5f23331eadc4 in flatview_read ../system/physmem.c:2865
#5 0x5f23331ec2a5 in address_space_read_full ../system/physmem.c:2878
#6 0x5f23331ec2a5 in address_space_rw ../system/physmem.c:2906
#7 0x5f23326b7ad0 in ufs_dma_read_req_upiu ../hw/ufs/ufs.c:129
#8 0x5f23326b7ad0 in ufs_dma_read_upiu ../hw/ufs/ufs.c:185
#9 0x5f23326b7ad0 in ufs_exec_req ../hw/ufs/ufs.c:1021
#10 0x5f23326b7ad0 in ufs_process_req ../hw/ufs/ufs.c:1066
#11 0x5f2333a9160d in aio_bh_call ../util/async.c:171
#12 0x5f2333a91f45 in aio_bh_poll ../util/async.c:218
#13 0x5f2333a217a9 in aio_dispatch ../util/aio-posix.c:423
#14 0x5f2333a90d01 in aio_ctx_dispatch ../util/async.c:360
#15 0x7f9f985c4d3a in g_main_context_dispatch
(/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x55d3a)
#16 0x5f2333a9690f in glib_pollfds_poll ../util/main-loop.c:287
#17 0x5f2333a9690f in os_host_main_loop_wait ../util/main-loop.c:310
#18 0x5f2333a9690f in main_loop_wait ../util/main-loop.c:589
#19 0x5f23329370e0 in qemu_main_loop ../system/runstate.c:783
#20 0x5f23333b4d7a in qemu_default_main ../system/main.c:37
#21 0x7f9f97629d8f in __libc_start_call_main
../sysdeps/nptl/libc_start_call_main.h:58
#22 0x7f9f97629e3f in __libc_start_main_impl ../csu/libc-start.c:392
#23 0x5f2331c8df64 in _start
(/home/joey/repo/qemu/build/qemu-system-x86_64+0x2ea8f64)
0x62a000011200 is located 0 bytes to the right of 20480-byte region
[0x62a00000c200,0x62a000011200)
allocated by thread T0 here:
#0 0x7f9f990b4a57 in __interceptor_calloc
../../../../src/libsanitizer/asan/asan_malloc_linux.cpp:154
#1 0x7f9f985cdc50 in g_malloc0
(/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x5ec50)
#2 0xf0e808deae299ff (<unknown module>)
SUMMARY: AddressSanitizer: heap-buffer-overflow
../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:827
in __interceptor_memcpy
Shadow bytes around the buggy address:
0x0c547fffa1f0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c547fffa200: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c547fffa210: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c547fffa220: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
0x0c547fffa230: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c547fffa240:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c547fffa250: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c547fffa260: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c547fffa270: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c547fffa280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
0x0c547fffa290: 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
==3619819==ABORTING
And Here is a simple PoC:
cat << EOF \
qemu-system-x86_64 \
-display none -machine accel=qtest -m 512M -M q35 -nodefaults -drive \
file=null-co://,if=none,id=disk0 -device ufs,id=ufs_bus -device \
ufs-lu,drive=disk0,bus=ufs_bus -qtest stdio
outl 0xcf8 0x80000810
outl 0xcfc 0xe0000000
outl 0xcf8 0x80000804
outw 0xcfc 0x06
write 0xe0000058 0x1 0xa7
write 0xa 0x1 0x50
EOF