88 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
		
		
			
		
	
	
			88 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
|   | From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 | ||
|  | From: Fiona Ebner <f.ebner@proxmox.com> | ||
|  | Date: Thu, 16 May 2024 12:59:52 +0200 | ||
|  | Subject: [PATCH] Revert "virtio-pci: fix use of a released vector" | ||
|  | 
 | ||
|  | This reverts commit 2ce6cff94df2650c460f809e5ad263f1d22507c0. | ||
|  | 
 | ||
|  | The fix causes some issues: | ||
|  | https://gitlab.com/qemu-project/qemu/-/issues/2321 | ||
|  | https://gitlab.com/qemu-project/qemu/-/issues/2334 | ||
|  | 
 | ||
|  | The CVE fixed by commit 2ce6cff94d ("virtio-pci: fix use of a released | ||
|  | vector") is CVE-2024-4693 [0] and allows a malicious guest that | ||
|  | controls the boot process in the guest to crash its QEMU process. | ||
|  | 
 | ||
|  | The issues sound worse than the CVE, so revert until there is a proper | ||
|  | fix. | ||
|  | 
 | ||
|  | [0]: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2024-4693 | ||
|  | 
 | ||
|  | Signed-off-by: Fiona Ebner <f.ebner@proxmox.com> | ||
|  | ---
 | ||
|  |  hw/virtio/virtio-pci.c | 37 ++----------------------------------- | ||
|  |  1 file changed, 2 insertions(+), 35 deletions(-) | ||
|  | 
 | ||
|  | diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
 | ||
|  | index cb159fd078..cb6940fc0e 100644
 | ||
|  | --- a/hw/virtio/virtio-pci.c
 | ||
|  | +++ b/hw/virtio/virtio-pci.c
 | ||
|  | @@ -1424,38 +1424,6 @@ static int virtio_pci_add_mem_cap(VirtIOPCIProxy *proxy,
 | ||
|  |      return offset; | ||
|  |  } | ||
|  |   | ||
|  | -static void virtio_pci_set_vector(VirtIODevice *vdev,
 | ||
|  | -                                  VirtIOPCIProxy *proxy,
 | ||
|  | -                                  int queue_no, uint16_t old_vector,
 | ||
|  | -                                  uint16_t new_vector)
 | ||
|  | -{
 | ||
|  | -    bool kvm_irqfd = (vdev->status & VIRTIO_CONFIG_S_DRIVER_OK) &&
 | ||
|  | -        msix_enabled(&proxy->pci_dev) && kvm_msi_via_irqfd_enabled();
 | ||
|  | -
 | ||
|  | -    if (new_vector == old_vector) {
 | ||
|  | -        return;
 | ||
|  | -    }
 | ||
|  | -
 | ||
|  | -    /*
 | ||
|  | -     * If the device uses irqfd and the vector changes after DRIVER_OK is
 | ||
|  | -     * set, we need to release the old vector and set up the new one.
 | ||
|  | -     * Otherwise just need to set the new vector on the device.
 | ||
|  | -     */
 | ||
|  | -    if (kvm_irqfd && old_vector != VIRTIO_NO_VECTOR) {
 | ||
|  | -        kvm_virtio_pci_vector_release_one(proxy, queue_no);
 | ||
|  | -    }
 | ||
|  | -    /* Set the new vector on the device. */
 | ||
|  | -    if (queue_no == VIRTIO_CONFIG_IRQ_IDX) {
 | ||
|  | -        vdev->config_vector = new_vector;
 | ||
|  | -    } else {
 | ||
|  | -        virtio_queue_set_vector(vdev, queue_no, new_vector);
 | ||
|  | -    }
 | ||
|  | -    /* If the new vector changed need to set it up. */
 | ||
|  | -    if (kvm_irqfd && new_vector != VIRTIO_NO_VECTOR) {
 | ||
|  | -        kvm_virtio_pci_vector_use_one(proxy, queue_no);
 | ||
|  | -    }
 | ||
|  | -}
 | ||
|  | -
 | ||
|  |  int virtio_pci_add_shm_cap(VirtIOPCIProxy *proxy, | ||
|  |                             uint8_t bar, uint64_t offset, uint64_t length, | ||
|  |                             uint8_t id) | ||
|  | @@ -1602,8 +1570,7 @@ static void virtio_pci_common_write(void *opaque, hwaddr addr,
 | ||
|  |          } else { | ||
|  |              val = VIRTIO_NO_VECTOR; | ||
|  |          } | ||
|  | -        virtio_pci_set_vector(vdev, proxy, VIRTIO_CONFIG_IRQ_IDX,
 | ||
|  | -                              vdev->config_vector, val);
 | ||
|  | +        vdev->config_vector = val;
 | ||
|  |          break; | ||
|  |      case VIRTIO_PCI_COMMON_STATUS: | ||
|  |          if (!(val & VIRTIO_CONFIG_S_DRIVER_OK)) { | ||
|  | @@ -1643,7 +1610,7 @@ static void virtio_pci_common_write(void *opaque, hwaddr addr,
 | ||
|  |          } else { | ||
|  |              val = VIRTIO_NO_VECTOR; | ||
|  |          } | ||
|  | -        virtio_pci_set_vector(vdev, proxy, vdev->queue_sel, vector, val);
 | ||
|  | +        virtio_queue_set_vector(vdev, vdev->queue_sel, val);
 | ||
|  |          break; | ||
|  |      case VIRTIO_PCI_COMMON_Q_ENABLE: | ||
|  |          if (val == 1) { |