Re: [Qemu-devel] [PATCH V2 1/4] vmxnet3: validate interrupt indices coming from guest
* Dmitry Fleytman (dmi...@daynix.com) wrote: CVE-2013-4544 Signed-off-by: Dmitry Fleytman dmi...@daynix.com Reported-by: Michael S. Tsirkin m...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com Reviewed-by: Dr. David Alan Gilbert dgilb...@redhat.com --- hw/net/vmxnet3.c | 36 ++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index 5be807c..0b317f8 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -52,6 +52,9 @@ #define VMXNET3_DEVICE_VERSION0x1 #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))) @@ -1305,6 +1308,34 @@ static bool vmxnet3_verify_intx(VMXNET3State *s, int intx) (pci_get_byte(s-parent_obj.config + PCI_INTERRUPT_PIN) - 1)); } +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; @@ -1447,6 +1478,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(); @@ -2005,7 +2038,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) @@ -2016,7 +2048,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); -- 1.8.5.3 -- Dr. David Alan Gilbert / dgilb...@redhat.com / Manchester, UK
[Qemu-devel] [PATCH V2 1/4] vmxnet3: validate interrupt indices coming from guest
CVE-2013-4544 Signed-off-by: Dmitry Fleytman dmi...@daynix.com Reported-by: Michael S. Tsirkin m...@redhat.com Signed-off-by: Michael S. Tsirkin m...@redhat.com --- hw/net/vmxnet3.c | 36 ++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c index 5be807c..0b317f8 100644 --- a/hw/net/vmxnet3.c +++ b/hw/net/vmxnet3.c @@ -52,6 +52,9 @@ #define VMXNET3_DEVICE_VERSION0x1 #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))) @@ -1305,6 +1308,34 @@ static bool vmxnet3_verify_intx(VMXNET3State *s, int intx) (pci_get_byte(s-parent_obj.config + PCI_INTERRUPT_PIN) - 1)); } +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; @@ -1447,6 +1478,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(); @@ -2005,7 +2038,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) @@ -2016,7 +2048,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); -- 1.8.5.3