From: Dmitry Fleytman Date: Fri, 4 Apr 2014 09:45:19 +0000 (+0300) Subject: vmxnet3: validate interrupt indices coming from guest X-Git-Tag: qemu-xen-4.4.3-rc1~40 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=ede728f155f57f22c602bc45252133040fbb90d5;p=qemu-xen.git vmxnet3: validate interrupt indices coming from guest CVE-2013-4544 Signed-off-by: Dmitry Fleytman Reported-by: Michael S. Tsirkin Signed-off-by: Michael S. Tsirkin Reviewed-by: Dr. David Alan Gilbert Message-id: 1396604722-11902-2-git-send-email-dmitry@daynix.com Signed-off-by: Peter Maydell Signed-off-by: Stefano Stabellini Conflicts: hw/net/vmxnet3.c --- diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index 49c2466434..6ae39a45f8 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -52,6 +52,9 @@ #define VMXNET3_DEVICE_VERSION 0x1 #define VMXNET3_DEVICE_REVISION 0x1 +/* Number of interrupt vectors for non-MSIx modes */ +#define VMXNET3_MAX_NMSIX_INTRS (1) + /* Macros for rings descriptors access */ #define VMXNET3_READ_TX_QUEUE_DESCR8(dpa, field) \ (vmw_shmem_ld8(dpa + offsetof(struct Vmxnet3_TxQueueDesc, field))) @@ -1299,6 +1302,34 @@ static void vmxnet3_update_features(VMXNET3State *s) } } +static void vmxnet3_validate_interrupt_idx(bool is_msix, int idx) +{ + int max_ints = is_msix ? VMXNET3_MAX_INTRS : VMXNET3_MAX_NMSIX_INTRS; + if (idx >= max_ints) { + hw_error("Bad interrupt index: %d\n", idx); + } +} + +static void vmxnet3_validate_interrupts(VMXNET3State *s) +{ + int i; + + VMW_CFPRN("Verifying event interrupt index (%d)", s->event_int_idx); + vmxnet3_validate_interrupt_idx(s->msix_used, s->event_int_idx); + + for (i = 0; i < s->txq_num; i++) { + int idx = s->txq_descr[i].intr_idx; + VMW_CFPRN("Verifying TX queue %d interrupt index (%d)", i, idx); + vmxnet3_validate_interrupt_idx(s->msix_used, idx); + } + + for (i = 0; i < s->rxq_num; i++) { + int idx = s->rxq_descr[i].intr_idx; + VMW_CFPRN("Verifying RX queue %d interrupt index (%d)", i, idx); + vmxnet3_validate_interrupt_idx(s->msix_used, idx); + } +} + static void vmxnet3_activate_device(VMXNET3State *s) { int i; @@ -1438,6 +1469,8 @@ static void vmxnet3_activate_device(VMXNET3State *s) sizeof(s->rxq_descr[i].rxq_stats)); } + vmxnet3_validate_interrupts(s); + /* Make sure everything is in place before device activation */ smp_wmb(); @@ -1998,7 +2031,6 @@ vmxnet3_cleanup_msix(VMXNET3State *s) } } -#define VMXNET3_MSI_NUM_VECTORS (1) #define VMXNET3_MSI_OFFSET (0x50) #define VMXNET3_USE_64BIT (true) #define VMXNET3_PER_VECTOR_MASK (false) @@ -2009,7 +2041,7 @@ vmxnet3_init_msi(VMXNET3State *s) PCIDevice *d = PCI_DEVICE(s); int res; - res = msi_init(d, VMXNET3_MSI_OFFSET, VMXNET3_MSI_NUM_VECTORS, + res = msi_init(d, VMXNET3_MSI_OFFSET, VMXNET3_MAX_NMSIX_INTRS, VMXNET3_USE_64BIT, VMXNET3_PER_VECTOR_MASK); if (0 > res) { VMW_WRPRN("Failed to initialize MSI, error %d", res);