|
Mark McLoughlin |
1c9931 |
From 2b76390876db26fb279d26de86b2c0b8260ff142 Mon Sep 17 00:00:00 2001
|
|
Mark McLoughlin |
1c9931 |
From: Glauber Costa <glommer@redhat.com>
|
|
Mark McLoughlin |
1c9931 |
Date: Wed, 23 Sep 2009 09:49:43 +0100
|
|
Mark McLoughlin |
1c9931 |
Subject: [PATCH] Correctly free nd structure
|
|
Mark McLoughlin |
1c9931 |
|
|
Mark McLoughlin |
1c9931 |
When we "free" a NICInfo structure, we can leak pointers, since we don't do
|
|
Mark McLoughlin |
1c9931 |
much more than setting used = 0.
|
|
Mark McLoughlin |
1c9931 |
|
|
Mark McLoughlin |
1c9931 |
We free() the model parameter, but we don't set it to NULL. This means that
|
|
Mark McLoughlin |
1c9931 |
a new user of this structure will see garbage in there. It was not noticed
|
|
Mark McLoughlin |
1c9931 |
before because reusing a NICInfo is not that common, but it can be, for
|
|
Mark McLoughlin |
1c9931 |
users of device pci hotplug.
|
|
Mark McLoughlin |
1c9931 |
|
|
Mark McLoughlin |
1c9931 |
A user hit it, described at https://bugzilla.redhat.com/524022
|
|
Mark McLoughlin |
1c9931 |
|
|
Mark McLoughlin |
1c9931 |
This patch memset's the whole structure, guaranteeing that anyone reusing it
|
|
Mark McLoughlin |
1c9931 |
will see a fresh NICinfo. Also, we free some other strings that are currently
|
|
Mark McLoughlin |
1c9931 |
leaking.
|
|
Mark McLoughlin |
1c9931 |
|
|
Mark McLoughlin |
1c9931 |
This codebase is quite old, so this patch should feed all stable trees.
|
|
Mark McLoughlin |
1c9931 |
|
|
Mark McLoughlin |
1c9931 |
Signed-off-by: Glauber Costa <glommer@redhat.com>
|
|
Mark McLoughlin |
1c9931 |
Signed-off-by: Mark McLoughlin <markmc@redhat.com>
|
|
Mark McLoughlin |
1c9931 |
Fedora-patch: qemu-correctly-free-nic-info-structure.patch
|
|
Mark McLoughlin |
1c9931 |
---
|
|
Mark McLoughlin |
1c9931 |
net.c | 16 +++++++++++-----
|
|
Mark McLoughlin |
1c9931 |
net.h | 8 ++++----
|
|
Mark McLoughlin |
1c9931 |
vl.c | 2 +-
|
|
Mark McLoughlin |
1c9931 |
3 files changed, 16 insertions(+), 10 deletions(-)
|
|
Mark McLoughlin |
1c9931 |
|
|
Mark McLoughlin |
1c9931 |
diff --git a/net.c b/net.c
|
|
Mark McLoughlin |
1c9931 |
index 61c9649..b58945f 100644
|
|
Mark McLoughlin |
1c9931 |
--- a/net.c
|
|
Mark McLoughlin |
1c9931 |
+++ b/net.c
|
|
Mark McLoughlin |
1c9931 |
@@ -2564,7 +2564,7 @@ void qemu_check_nic_model_list(NICInfo *nd, const char * const *models,
|
|
Mark McLoughlin |
1c9931 |
int i, exit_status = 0;
|
|
Mark McLoughlin |
1c9931 |
|
|
Mark McLoughlin |
1c9931 |
if (!nd->model)
|
|
Mark McLoughlin |
1c9931 |
- nd->model = strdup(default_model);
|
|
Mark McLoughlin |
1c9931 |
+ nd->model = qemu_strdup(default_model);
|
|
Mark McLoughlin |
1c9931 |
|
|
Mark McLoughlin |
1c9931 |
if (strcmp(nd->model, "?") != 0) {
|
|
Mark McLoughlin |
1c9931 |
for (i = 0 ; models[i]; i++)
|
|
Mark McLoughlin |
1c9931 |
@@ -2634,6 +2634,7 @@ int net_client_init(Monitor *mon, const char *device, const char *p)
|
|
Mark McLoughlin |
1c9931 |
goto out;
|
|
Mark McLoughlin |
1c9931 |
}
|
|
Mark McLoughlin |
1c9931 |
nd = &nd_table[idx];
|
|
Mark McLoughlin |
1c9931 |
+ memset(nd, 0, sizeof(*nd));
|
|
Mark McLoughlin |
1c9931 |
macaddr = nd->macaddr;
|
|
Mark McLoughlin |
1c9931 |
macaddr[0] = 0x52;
|
|
Mark McLoughlin |
1c9931 |
macaddr[1] = 0x54;
|
|
Mark McLoughlin |
1c9931 |
@@ -2650,13 +2651,13 @@ int net_client_init(Monitor *mon, const char *device, const char *p)
|
|
Mark McLoughlin |
1c9931 |
}
|
|
Mark McLoughlin |
1c9931 |
}
|
|
Mark McLoughlin |
1c9931 |
if (get_param_value(buf, sizeof(buf), "model", p)) {
|
|
Mark McLoughlin |
1c9931 |
- nd->model = strdup(buf);
|
|
Mark McLoughlin |
1c9931 |
+ nd->model = qemu_strdup(buf);
|
|
Mark McLoughlin |
1c9931 |
}
|
|
Mark McLoughlin |
1c9931 |
if (get_param_value(buf, sizeof(buf), "addr", p)) {
|
|
Mark McLoughlin |
1c9931 |
- nd->devaddr = strdup(buf);
|
|
Mark McLoughlin |
1c9931 |
+ nd->devaddr = qemu_strdup(buf);
|
|
Mark McLoughlin |
1c9931 |
}
|
|
Mark McLoughlin |
1c9931 |
if (get_param_value(buf, sizeof(buf), "id", p)) {
|
|
Mark McLoughlin |
1c9931 |
- nd->id = strdup(buf);
|
|
Mark McLoughlin |
1c9931 |
+ nd->id = qemu_strdup(buf);
|
|
Mark McLoughlin |
1c9931 |
}
|
|
Mark McLoughlin |
1c9931 |
nd->nvectors = NIC_NVECTORS_UNSPECIFIED;
|
|
Mark McLoughlin |
1c9931 |
if (get_param_value(buf, sizeof(buf), "vectors", p)) {
|
|
Mark McLoughlin |
1c9931 |
@@ -3003,8 +3004,13 @@ void net_client_uninit(NICInfo *nd)
|
|
Mark McLoughlin |
1c9931 |
{
|
|
Mark McLoughlin |
1c9931 |
nd->vlan->nb_guest_devs--;
|
|
Mark McLoughlin |
1c9931 |
nb_nics--;
|
|
Mark McLoughlin |
1c9931 |
+
|
|
Mark McLoughlin |
1c9931 |
+ qemu_free(nd->model);
|
|
Mark McLoughlin |
1c9931 |
+ qemu_free(nd->name);
|
|
Mark McLoughlin |
1c9931 |
+ qemu_free(nd->devaddr);
|
|
Mark McLoughlin |
1c9931 |
+ qemu_free(nd->id);
|
|
Mark McLoughlin |
1c9931 |
+
|
|
Mark McLoughlin |
1c9931 |
nd->used = 0;
|
|
Mark McLoughlin |
1c9931 |
- free((void *)nd->model);
|
|
Mark McLoughlin |
1c9931 |
}
|
|
Mark McLoughlin |
1c9931 |
|
|
Mark McLoughlin |
1c9931 |
static int net_host_check_device(const char *device)
|
|
Mark McLoughlin |
1c9931 |
diff --git a/net.h b/net.h
|
|
Mark McLoughlin |
1c9931 |
index b172691..ec78d0a 100644
|
|
Mark McLoughlin |
1c9931 |
--- a/net.h
|
|
Mark McLoughlin |
1c9931 |
+++ b/net.h
|
|
Mark McLoughlin |
1c9931 |
@@ -100,10 +100,10 @@ enum {
|
|
Mark McLoughlin |
1c9931 |
|
|
Mark McLoughlin |
1c9931 |
struct NICInfo {
|
|
Mark McLoughlin |
1c9931 |
uint8_t macaddr[6];
|
|
Mark McLoughlin |
1c9931 |
- const char *model;
|
|
Mark McLoughlin |
1c9931 |
- const char *name;
|
|
Mark McLoughlin |
1c9931 |
- const char *devaddr;
|
|
Mark McLoughlin |
1c9931 |
- const char *id;
|
|
Mark McLoughlin |
1c9931 |
+ char *model;
|
|
Mark McLoughlin |
1c9931 |
+ char *name;
|
|
Mark McLoughlin |
1c9931 |
+ char *devaddr;
|
|
Mark McLoughlin |
1c9931 |
+ char *id;
|
|
Mark McLoughlin |
1c9931 |
VLANState *vlan;
|
|
Mark McLoughlin |
1c9931 |
VLANClientState *vc;
|
|
Mark McLoughlin |
1c9931 |
void *private;
|
|
Mark McLoughlin |
1c9931 |
diff --git a/vl.c b/vl.c
|
|
Mark McLoughlin |
1c9931 |
index 26bced8..d7c7ab1 100644
|
|
Mark McLoughlin |
1c9931 |
--- a/vl.c
|
|
Mark McLoughlin |
1c9931 |
+++ b/vl.c
|
|
Mark McLoughlin |
1c9931 |
@@ -2594,7 +2594,7 @@ static int usb_device_add(const char *devname, int is_hotplug)
|
|
Mark McLoughlin |
1c9931 |
|
|
Mark McLoughlin |
1c9931 |
if (net_client_init(NULL, "nic", p) < 0)
|
|
Mark McLoughlin |
1c9931 |
return -1;
|
|
Mark McLoughlin |
1c9931 |
- nd_table[nic].model = "usb";
|
|
Mark McLoughlin |
1c9931 |
+ nd_table[nic].model = qemu_strdup("usb");
|
|
Mark McLoughlin |
1c9931 |
dev = usb_net_init(&nd_table[nic]);
|
|
Mark McLoughlin |
1c9931 |
} else if (!strcmp(devname, "bt") || strstart(devname, "bt:", &p)) {
|
|
Mark McLoughlin |
1c9931 |
dev = usb_bt_init(devname[2] ? hci_init(p) :
|
|
Mark McLoughlin |
1c9931 |
--
|
|
Mark McLoughlin |
1c9931 |
1.6.2.5
|
|
Mark McLoughlin |
1c9931 |
|