From: "Denis V. Lunev" <[email protected]> qemu-kvm aborts a few seconds after starting a VM with a passed-through GPU whose PCI_INTERRUPT_PIN comes back as an out-of-range value: vfio_intx_enable() only guards against pin == 0 and stores vdev->intx.pin = pin - 1 with no upper-bound check. That value later reaches pci_irq_handler()'s assert(0 <= irq_num && irq_num < PCI_NUM_PINS) via pci_irq_deassert() -> pci_set_irq(), aborting the process.
Legal PCI_INTERRUPT_PIN values are 0 (no legacy interrupt) or 1-PCI_NUM_PINS (INTA-INTD); reject anything else before it reaches vdev->intx.pin, whether the out-of-range value came from a read failure (now caught by the previous commit) or was handed back as data by the device itself. Signed-off-by: Denis V. Lunev <[email protected]> CC: Alex Williamson <[email protected]> CC: Cédric Le Goater <[email protected]> Link: https://lore.kernel.org/qemu-devel/[email protected] Reviewed-by: Cédric Le Goater <[email protected]> Reviewed-by: Philippe Mathieu-Daudé <[email protected]> Signed-off-by: Cédric Le Goater <[email protected]> (cherry picked from commit 86abb10256a58d50513d1f9c65652b7b6b7faafc) Signed-off-by: Michael Tokarev <[email protected]> diff --git a/hw/vfio/pci.c b/hw/vfio/pci.c index b24c3b35113..5c192ee54b4 100644 --- a/hw/vfio/pci.c +++ b/hw/vfio/pci.c @@ -346,6 +346,11 @@ static bool vfio_intx_enable(VFIOPCIDevice *vdev, Error **errp) return true; } + if (pin > PCI_NUM_PINS) { + error_setg(errp, "invalid PCI interrupt pin %d", pin); + return false; + } + /* * Do not alter interrupt state during vfio_realize and cpr load. * The incoming state is cleared thereafter. -- 2.47.3
