From 7c16b5bbb6c0f797945327d17e4be60f25a4427d Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Wed, 3 Feb 2021 14:18:27 +0100 Subject: pci: reject too large ROMs get_image_size() returns an int64_t, which pci_add_option_rom() assigns to an "int" without any range checking. A 32-bit BAR could be up to 2 GiB in size, so reject anything above it. In order to accomodate a rounded-up size of 2 GiB, change pci_patch_ids's size argument to unsigned. Reviewed-by: Peter Xu Reviewed-by: Philippe Mathieu-Daudé Reviewed-by: Laszlo Ersek Signed-off-by: Paolo Bonzini Message-Id: <20210203131828.156467-2-pbonzini@redhat.com> Reviewed-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: David Edmondson --- hw/pci/pci.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) (limited to 'hw/pci') diff --git a/hw/pci/pci.c b/hw/pci/pci.c index 512e9042ff..58560c044d 100644 --- a/hw/pci/pci.c +++ b/hw/pci/pci.c @@ -25,6 +25,7 @@ #include "qemu/osdep.h" #include "qemu-common.h" #include "qemu/datadir.h" +#include "qemu/units.h" #include "hw/irq.h" #include "hw/pci/pci.h" #include "hw/pci/pci_bridge.h" @@ -2234,7 +2235,7 @@ static uint8_t pci_find_capability_at_offset(PCIDevice *pdev, uint8_t offset) /* Patch the PCI vendor and device ids in a PCI rom image if necessary. This is needed for an option rom which is used for more than one device. */ -static void pci_patch_ids(PCIDevice *pdev, uint8_t *ptr, int size) +static void pci_patch_ids(PCIDevice *pdev, uint8_t *ptr, uint32_t size) { uint16_t vendor_id; uint16_t device_id; @@ -2292,7 +2293,7 @@ static void pci_patch_ids(PCIDevice *pdev, uint8_t *ptr, int size) static void pci_add_option_rom(PCIDevice *pdev, bool is_default_rom, Error **errp) { - int size; + int64_t size; char *path; void *ptr; char name[32]; @@ -2342,6 +2343,11 @@ static void pci_add_option_rom(PCIDevice *pdev, bool is_default_rom, error_setg(errp, "romfile \"%s\" is empty", pdev->romfile); g_free(path); return; + } else if (size > 2 * GiB) { + error_setg(errp, "romfile \"%s\" too large (size cannot exceed 2 GiB)", + pdev->romfile); + g_free(path); + return; } size = pow2ceil(size); -- cgit v1.2.3-55-g7522