QEMU qxl_phys2virt Unsafe Address Translation Lead to OOB Read
Hello,
A security bug found in QEMU months ago was reported to the qemu-security@nongnu.org mailing list. However, it is still not fixed till now. After coordination with maintainer Gerd Hoffmann and Mauro Matteo Cascella from Red Hat Product Security, a new issue is advised to be opened here.
The details are as follows:
QEMU version: the latest, v7.0.0 tested
Host & Guest architecture: x86_64
Affected code: void *qxl_phys2virt(PCIQXLDevice *qxl, QXLPHYSICAL pqxl, int group_id)
Configuration: default installed guest by Virt Manager.
Stack traces: interface_get_cursor_command()->qxl_track_command()
Reproducer steps:
On Windows 10 with QEMU v7.0.0 x64 installed. https://qemu.weilnetz.de/w64/2022/qemu-w64-setup-20220419.exe
-
.\qemu-system-x86_64.exe -machine q35 -m 4G -smp 2 -hda .\disk.qcow2 -vga qxl;
-
attach WinDbg to the QEMU process;
-
in a linux guest, run sudo ./poc [bar0] [bar3]
The QEMU process should crash on segfault.
Root Cause: qxl_phys2virt() does not check the size of the structure pointed to by the guest physical address pqxl, if pqxl is near the end of the bar1 space, subsequent access to its fields may read pass the end into adjacent pages.
Proposed fix: Another function void *memslot_get_virt(RedMemSlotInfo *info, QXLPHYSICAL addr, uint32_t add_size, int group_id) implemented in Spice server v0.14.3 also does the same work of QXLPHYSICAL address translation, but checks the size of the structure at addr, maybe we can add the same size check to qxl_phys2virt().
Acknowledgement: Wenxu Yin @awxylitol
Have a good day !