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