Re: [Qemu-devel] [PATCH V2 1/4] vmxnet3: validate interrupt indices coming from guest

2014-04-11 Thread Dr. David Alan Gilbert
* 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

2014-04-04 Thread Dmitry Fleytman
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