b24b7f1
From: P J P <ppandit@redhat.com>
b24b7f1
Date: Tue, 15 Dec 2015 12:27:54 +0530
b24b7f1
Subject: [PATCH] net: vmxnet3: avoid memory leakage in activate_device
b24b7f1
b24b7f1
Vmxnet3 device emulator does not check if the device is active
b24b7f1
before activating it, also it did not free the transmit & receive
b24b7f1
buffers while deactivating the device, thus resulting in memory
b24b7f1
leakage on the host. This patch fixes both these issues to avoid
b24b7f1
host memory leakage.
b24b7f1
b24b7f1
Reported-by: Qinghao Tang <luodalongde@gmail.com>
b24b7f1
Reviewed-by: Dmitry Fleytman <dmitry@daynix.com>
b24b7f1
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
b24b7f1
Cc: qemu-stable@nongnu.org
b24b7f1
Signed-off-by: Jason Wang <jasowang@redhat.com>
b24b7f1
(cherry picked from commit aa4a3dce1c88ed51b616806b8214b7c8428b7470)
b24b7f1
---
b24b7f1
 hw/net/vmxnet3.c | 24 ++++++++++++++++--------
b24b7f1
 1 file changed, 16 insertions(+), 8 deletions(-)
b24b7f1
b24b7f1
diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c
b24b7f1
index 37373e5..2b4aad7 100644
b24b7f1
--- a/hw/net/vmxnet3.c
b24b7f1
+++ b/hw/net/vmxnet3.c
b24b7f1
@@ -1194,8 +1194,13 @@ static void vmxnet3_reset_mac(VMXNET3State *s)
b24b7f1
 
b24b7f1
 static void vmxnet3_deactivate_device(VMXNET3State *s)
b24b7f1
 {
b24b7f1
-    VMW_CBPRN("Deactivating vmxnet3...");
b24b7f1
-    s->device_active = false;
b24b7f1
+    if (s->device_active) {
b24b7f1
+        VMW_CBPRN("Deactivating vmxnet3...");
b24b7f1
+        vmxnet_tx_pkt_reset(s->tx_pkt);
b24b7f1
+        vmxnet_tx_pkt_uninit(s->tx_pkt);
b24b7f1
+        vmxnet_rx_pkt_uninit(s->rx_pkt);
b24b7f1
+        s->device_active = false;
b24b7f1
+    }
b24b7f1
 }
b24b7f1
 
b24b7f1
 static void vmxnet3_reset(VMXNET3State *s)
b24b7f1
@@ -1204,7 +1209,6 @@ static void vmxnet3_reset(VMXNET3State *s)
b24b7f1
 
b24b7f1
     vmxnet3_deactivate_device(s);
b24b7f1
     vmxnet3_reset_interrupt_states(s);
b24b7f1
-    vmxnet_tx_pkt_reset(s->tx_pkt);
b24b7f1
     s->drv_shmem = 0;
b24b7f1
     s->tx_sop = true;
b24b7f1
     s->skip_current_tx_pkt = false;
b24b7f1
@@ -1431,6 +1435,12 @@ static void vmxnet3_activate_device(VMXNET3State *s)
b24b7f1
         return;
b24b7f1
     }
b24b7f1
 
b24b7f1
+    /* Verify if device is active */
b24b7f1
+    if (s->device_active) {
b24b7f1
+        VMW_CFPRN("Vmxnet3 device is active");
b24b7f1
+        return;
b24b7f1
+    }
b24b7f1
+
b24b7f1
     vmxnet3_adjust_by_guest_type(s);
b24b7f1
     vmxnet3_update_features(s);
b24b7f1
     vmxnet3_update_pm_state(s);
b24b7f1
@@ -1627,7 +1637,7 @@ static void vmxnet3_handle_command(VMXNET3State *s, uint64_t cmd)
b24b7f1
         break;
b24b7f1
 
b24b7f1
     case VMXNET3_CMD_QUIESCE_DEV:
b24b7f1
-        VMW_CBPRN("Set: VMXNET3_CMD_QUIESCE_DEV - pause the device");
b24b7f1
+        VMW_CBPRN("Set: VMXNET3_CMD_QUIESCE_DEV - deactivate the device");
b24b7f1
         vmxnet3_deactivate_device(s);
b24b7f1
         break;
b24b7f1
 
b24b7f1
@@ -1741,7 +1751,7 @@ vmxnet3_io_bar1_write(void *opaque,
b24b7f1
          * shared address only after we get the high part
b24b7f1
          */
b24b7f1
         if (val == 0) {
b24b7f1
-            s->device_active = false;
b24b7f1
+            vmxnet3_deactivate_device(s);
b24b7f1
         }
b24b7f1
         s->temp_shared_guest_driver_memory = val;
b24b7f1
         s->drv_shmem = 0;
b24b7f1
@@ -2021,9 +2031,7 @@ static bool vmxnet3_peer_has_vnet_hdr(VMXNET3State *s)
b24b7f1
 static void vmxnet3_net_uninit(VMXNET3State *s)
b24b7f1
 {
b24b7f1
     g_free(s->mcast_list);
b24b7f1
-    vmxnet_tx_pkt_reset(s->tx_pkt);
b24b7f1
-    vmxnet_tx_pkt_uninit(s->tx_pkt);
b24b7f1
-    vmxnet_rx_pkt_uninit(s->rx_pkt);
b24b7f1
+    vmxnet3_deactivate_device(s);
b24b7f1
     qemu_del_nic(s->nic);
b24b7f1
 }
b24b7f1