From: Gerd Hoffmann Date: Mon, 12 Aug 2019 06:52:21 +0000 (+0200) Subject: display/bochs: fix pcie support X-Git-Url: http://git.maquefel.me/?a=commitdiff_plain;h=5e7bcdcfe69ce0fad66012b2cfb2035003c37eef;p=qemu.git display/bochs: fix pcie support Set QEMU_PCI_CAP_EXPRESS unconditionally in init(), then clear it in realize() in case the device is not connected to a PCIe bus. This makes sure the pci config space allocation is big enough, so accessing the PCIe extended config space doesn't overflow the pci config space buffer. PCI(e) config space is guest writable. Writes are limited by write mask (which probably is also filled with random stuff), so the guest can only flip enabled bits. But I suspect it still might be exploitable, so rather serious because it might be a host escape for the guest. On the other hand the device is probably not yet in widespread use. (For a QEMU version without this commit, a mitigation for the bug is available: use "-device bochs-display" as a conventional pci device only.) Cc: qemu-stable@nongnu.org Signed-off-by: Gerd Hoffmann Message-id: 20190812065221.20907-2-kraxel@redhat.com Reviewed-by: Alex Williamson Reviewed-by: Paolo Bonzini Signed-off-by: Peter Maydell --- diff --git a/hw/display/bochs-display.c b/hw/display/bochs-display.c index 582133dd71..8e83b5164b 100644 --- a/hw/display/bochs-display.c +++ b/hw/display/bochs-display.c @@ -297,9 +297,10 @@ static void bochs_display_realize(PCIDevice *dev, Error **errp) } if (pci_bus_is_express(pci_get_bus(dev))) { - dev->cap_present |= QEMU_PCI_CAP_EXPRESS; ret = pcie_endpoint_cap_init(dev, 0x80); assert(ret > 0); + } else { + dev->cap_present &= ~QEMU_PCI_CAP_EXPRESS; } memory_region_set_log(&s->vram, true, DIRTY_MEMORY_VGA); @@ -322,11 +323,15 @@ static void bochs_display_set_big_endian_fb(Object *obj, bool value, static void bochs_display_init(Object *obj) { + PCIDevice *dev = PCI_DEVICE(obj); + /* Expose framebuffer byteorder via QOM */ object_property_add_bool(obj, "big-endian-framebuffer", bochs_display_get_big_endian_fb, bochs_display_set_big_endian_fb, NULL); + + dev->cap_present |= QEMU_PCI_CAP_EXPRESS; } static void bochs_display_exit(PCIDevice *dev)