virtio-gpu: heap-buffer-overflow in virtio_gpu_disable_scanout
Hi, OSS-Fuzz found a recently-introduced problem in virtio-gpu/vga
Reproducer:
cat << EOF | ./qemu-system-i386 -display none -machine accel=qtest, -m \
512M,slots=1,maxmem=0xffff000000000000 -machine q35 -nodefaults -device \
virtio-gpu -device pc-dimm,id=nv1,memdev=mem1,addr=0xab2c00000000 -object \
memory-backend-ram,id=mem1,size=2M -qtest stdio
outl 0xcf8 0x80000820
outl 0xcfc 0xe0004000
outl 0xcf8 0x8000088f
outw 0xcfc 0x400
outl 0xcf8 0x8000088b
outw 0xcfc 0x2800
outl 0xcf8 0x80000894
outb 0xcfc 0x55
outl 0xcf8 0x8000088b
outw 0xcfc 0x2400
outl 0xcf8 0x80000894
outw 0xcfc 0xab2c
outl 0xcf8 0x80000804
outb 0xcfc 0x06
outl 0xcf8 0x8000088b
outw 0xcfc 0x1c00
outl 0xcf8 0x80000894
outw 0xcfc 0x1
write 0x58 0x1 0x01
write 0x103 0x1 0x03
write 0x104 0x1 0x01
write 0x12b 0x1 0x16
write 0xab2c00000000 0x1 0x03
write 0xab2c00000001 0x1 0x01
write 0xab2c0000000a 0x1 0x02
write 0xe0007003 0x1 0x00
EOF
Stack-trace:
qemu-system-i386: Virtqueue size exceeded
../hw/display/virtio-gpu.c:318:43: runtime error: index 22 out of bounds for type 'struct virtio_gpu_scanout [16]'
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior ../hw/display/virtio-gpu.c:318:43 in
=================================================================
==126992==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x62d0000270bc at pc 0x55f97ca4be34 bp 0x7ffdc5338f80 sp 0x7ffdc5338f78
READ of size 4 at 0x62d0000270bc thread T0
#0 0x55f97ca4be33 in virtio_gpu_disable_scanout /home/alxndr/Development/qemu/build/../hw/display/virtio-gpu.c:321:18
#1 0x55f97ca3d839 in virtio_gpu_set_scanout /home/alxndr/Development/qemu/build/../hw/display/virtio-gpu.c:596:9
#2 0x55f97ca3d839 in virtio_gpu_simple_process_cmd /home/alxndr/Development/qemu/build/../hw/display/virtio-gpu.c:799:9
#3 0x55f97ca45dd6 in virtio_gpu_process_cmdq /home/alxndr/Development/qemu/build/../hw/display/virtio-gpu.c:846:9
#4 0x55f97e099e86 in aio_bh_poll /home/alxndr/Development/qemu/build/../util/async.c:164:13
#5 0x55f97dfd755c in aio_dispatch /home/alxndr/Development/qemu/build/../util/aio-posix.c:381:5
#6 0x55f97e09e91c in aio_ctx_dispatch /home/alxndr/Development/qemu/build/../util/async.c:306:5
#7 0x7f3960d14baa in g_main_context_dispatch (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x51baa)
#8 0x55f97dfbf62c in glib_pollfds_poll /home/alxndr/Development/qemu/build/../util/main-loop.c:231:9
#9 0x55f97dfbf62c in os_host_main_loop_wait /home/alxndr/Development/qemu/build/../util/main-loop.c:254:5
#10 0x55f97dfbf62c in main_loop_wait /home/alxndr/Development/qemu/build/../util/main-loop.c:530:11
#11 0x55f97d0cf989 in qemu_main_loop /home/alxndr/Development/qemu/build/../softmmu/runstate.c:725:9
#12 0x55f97bc2d305 in main /home/alxndr/Development/qemu/build/../softmmu/main.c:50:5
#13 0x7f3960403d09 in __libc_start_main csu/../csu/libc-start.c:308:16
#14 0x55f97bb80cd9 in _start (/home/alxndr/Development/qemu/build/qemu-system-i386+0x2bf9cd9)
0x62d0000270bc is located 188 bytes to the right of 35840-byte region [0x62d00001e400,0x62d000027000)
allocated by thread T0 here:
#0 0x55f97bbfad4d in malloc (/home/alxndr/Development/qemu/build/qemu-system-i386+0x2c73d4d)
#1 0x7f3960d1aa88 in g_malloc (/usr/lib/x86_64-linux-gnu/libglib-2.0.so.0+0x57a88)
#2 0x55f97d5f15dd in qdev_new /home/alxndr/Development/qemu/build/../hw/core/qdev.c:153:19
#3 0x55f97c201199 in qdev_device_add /home/alxndr/Development/qemu/build/../softmmu/qdev-monitor.c:649:11
#4 0x55f97cf7952f in device_init_func /home/alxndr/Development/qemu/build/../softmmu/vl.c:1210:11
#5 0x55f97e094643 in qemu_opts_foreach /home/alxndr/Development/qemu/build/../util/qemu-option.c:1168:14
#6 0x55f97cf6904f in qemu_create_cli_devices /home/alxndr/Development/qemu/build/../softmmu/vl.c:2540:5
#7 0x55f97cf6904f in qmp_x_exit_preconfig /home/alxndr/Development/qemu/build/../softmmu/vl.c:2588:5
#8 0x55f97cf73329 in qemu_init /home/alxndr/Development/qemu/build/../softmmu/vl.c:3609:9
#9 0x55f97bc2d300 in main /home/alxndr/Development/qemu/build/../softmmu/main.c:49:5
#10 0x7f3960403d09 in __libc_start_main csu/../csu/libc-start.c:308:16
Bisected to e64d4b6a ("virtio-gpu: Refactor virtio_gpu_set_scanout")
pc-dimm is just there to set up a particularly high DMA address that the fuzzer used. It can probably be ignored for debugging purposes. -Alex
Edited by Alexander Bulekov