]>
Commit | Line | Data |
---|---|---|
c490868f WB |
1 | From 3ef66b01874fcc2fe3bfc73d2b61ee3a5b29fdb6 Mon Sep 17 00:00:00 2001 |
2 | From: Prasad J Pandit <pjp@fedoraproject.org> | |
3 | Date: Tue, 15 Dec 2015 12:17:28 +0530 | |
4 | Subject: [PATCH] net: vmxnet3: avoid memory leakage in activate_device | |
5 | ||
6 | Vmxnet3 device emulator does not check if the device is active | |
7 | before activating it, also it did not free the transmit & receive | |
8 | buffers while deactivating the device, thus resulting in memory | |
9 | leakage on the host. This patch fixes both these issues to avoid | |
10 | host memory leakage. | |
11 | ||
12 | Reported-by: Qinghao Tang <luodalongde@gmail.com> | |
13 | Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org> | |
14 | Reviewed-by: Dmitry Fleytman <dmitry@daynix.com> | |
15 | --- | |
16 | hw/net/vmxnet3.c | 24 ++++++++++++++++-------- | |
17 | 1 file changed, 16 insertions(+), 8 deletions(-) | |
18 | ||
19 | diff --git a/hw/net/vmxnet3.c b/hw/net/vmxnet3.c | |
20 | index 37373e5..2b4aad7 100644 | |
21 | --- a/hw/net/vmxnet3.c | |
22 | +++ b/hw/net/vmxnet3.c | |
23 | @@ -1194,8 +1194,13 @@ static void vmxnet3_reset_mac(VMXNET3State *s) | |
24 | ||
25 | static void vmxnet3_deactivate_device(VMXNET3State *s) | |
26 | { | |
27 | - VMW_CBPRN("Deactivating vmxnet3..."); | |
28 | - s->device_active = false; | |
29 | + if (s->device_active) { | |
30 | + VMW_CBPRN("Deactivating vmxnet3..."); | |
31 | + vmxnet_tx_pkt_reset(s->tx_pkt); | |
32 | + vmxnet_tx_pkt_uninit(s->tx_pkt); | |
33 | + vmxnet_rx_pkt_uninit(s->rx_pkt); | |
34 | + s->device_active = false; | |
35 | + } | |
36 | } | |
37 | ||
38 | static void vmxnet3_reset(VMXNET3State *s) | |
39 | @@ -1204,7 +1209,6 @@ static void vmxnet3_reset(VMXNET3State *s) | |
40 | ||
41 | vmxnet3_deactivate_device(s); | |
42 | vmxnet3_reset_interrupt_states(s); | |
43 | - vmxnet_tx_pkt_reset(s->tx_pkt); | |
44 | s->drv_shmem = 0; | |
45 | s->tx_sop = true; | |
46 | s->skip_current_tx_pkt = false; | |
47 | @@ -1431,6 +1435,12 @@ static void vmxnet3_activate_device(VMXNET3State *s) | |
48 | return; | |
49 | } | |
50 | ||
51 | + /* Verify if device is active */ | |
52 | + if (s->device_active) { | |
53 | + VMW_CFPRN("Vmxnet3 device is active"); | |
54 | + return; | |
55 | + } | |
56 | + | |
57 | vmxnet3_adjust_by_guest_type(s); | |
58 | vmxnet3_update_features(s); | |
59 | vmxnet3_update_pm_state(s); | |
60 | @@ -1627,7 +1637,7 @@ static void vmxnet3_handle_command(VMXNET3State *s, uint64_t cmd) | |
61 | break; | |
62 | ||
63 | case VMXNET3_CMD_QUIESCE_DEV: | |
64 | - VMW_CBPRN("Set: VMXNET3_CMD_QUIESCE_DEV - pause the device"); | |
65 | + VMW_CBPRN("Set: VMXNET3_CMD_QUIESCE_DEV - deactivate the device"); | |
66 | vmxnet3_deactivate_device(s); | |
67 | break; | |
68 | ||
69 | @@ -1741,7 +1751,7 @@ vmxnet3_io_bar1_write(void *opaque, | |
70 | * shared address only after we get the high part | |
71 | */ | |
72 | if (val == 0) { | |
73 | - s->device_active = false; | |
74 | + vmxnet3_deactivate_device(s); | |
75 | } | |
76 | s->temp_shared_guest_driver_memory = val; | |
77 | s->drv_shmem = 0; | |
78 | @@ -2021,9 +2031,7 @@ static bool vmxnet3_peer_has_vnet_hdr(VMXNET3State *s) | |
79 | static void vmxnet3_net_uninit(VMXNET3State *s) | |
80 | { | |
81 | g_free(s->mcast_list); | |
82 | - vmxnet_tx_pkt_reset(s->tx_pkt); | |
83 | - vmxnet_tx_pkt_uninit(s->tx_pkt); | |
84 | - vmxnet_rx_pkt_uninit(s->rx_pkt); | |
85 | + vmxnet3_deactivate_device(s); | |
86 | qemu_del_nic(s->nic); | |
87 | } | |
88 | ||
89 | -- | |
90 | 2.4.3 | |
91 |