vmxnet3: validate interrupt indices coming from guest
CVE-2013-4544 Signed-off-by: Dmitry Fleytman <dmitry@daynix.com> Reported-by: Michael S. Tsirkin <mst@redhat.com> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com> Message-id: 1396604722-11902-2-git-send-email-dmitry@daynix.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
		
							parent
							
								
									92b3eeadd9
								
							
						
					
					
						commit
						8c6c047899
					
				@ -52,6 +52,9 @@
 | 
				
			|||||||
#define VMXNET3_DEVICE_VERSION    0x1
 | 
					#define VMXNET3_DEVICE_VERSION    0x1
 | 
				
			||||||
#define VMXNET3_DEVICE_REVISION   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 */
 | 
					/* Macros for rings descriptors access */
 | 
				
			||||||
#define VMXNET3_READ_TX_QUEUE_DESCR8(dpa, field) \
 | 
					#define VMXNET3_READ_TX_QUEUE_DESCR8(dpa, field) \
 | 
				
			||||||
    (vmw_shmem_ld8(dpa + offsetof(struct Vmxnet3_TxQueueDesc, 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));
 | 
					           (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)
 | 
					static void vmxnet3_activate_device(VMXNET3State *s)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int i;
 | 
					    int i;
 | 
				
			||||||
@ -1447,6 +1478,8 @@ static void vmxnet3_activate_device(VMXNET3State *s)
 | 
				
			|||||||
               sizeof(s->rxq_descr[i].rxq_stats));
 | 
					               sizeof(s->rxq_descr[i].rxq_stats));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    vmxnet3_validate_interrupts(s);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Make sure everything is in place before device activation */
 | 
					    /* Make sure everything is in place before device activation */
 | 
				
			||||||
    smp_wmb();
 | 
					    smp_wmb();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -2005,7 +2038,6 @@ vmxnet3_cleanup_msix(VMXNET3State *s)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define VMXNET3_MSI_NUM_VECTORS   (1)
 | 
					 | 
				
			||||||
#define VMXNET3_MSI_OFFSET        (0x50)
 | 
					#define VMXNET3_MSI_OFFSET        (0x50)
 | 
				
			||||||
#define VMXNET3_USE_64BIT         (true)
 | 
					#define VMXNET3_USE_64BIT         (true)
 | 
				
			||||||
#define VMXNET3_PER_VECTOR_MASK   (false)
 | 
					#define VMXNET3_PER_VECTOR_MASK   (false)
 | 
				
			||||||
@ -2016,7 +2048,7 @@ vmxnet3_init_msi(VMXNET3State *s)
 | 
				
			|||||||
    PCIDevice *d = PCI_DEVICE(s);
 | 
					    PCIDevice *d = PCI_DEVICE(s);
 | 
				
			||||||
    int res;
 | 
					    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);
 | 
					                   VMXNET3_USE_64BIT, VMXNET3_PER_VECTOR_MASK);
 | 
				
			||||||
    if (0 > res) {
 | 
					    if (0 > res) {
 | 
				
			||||||
        VMW_WRPRN("Failed to initialize MSI, error %d", res);
 | 
					        VMW_WRPRN("Failed to initialize MSI, error %d", res);
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user