Blame qemu-correctly-free-nic-info-structure.patch

Mark McLoughlin 904b1d
From 3675a0dde74f890404f392e194f1adc6b24285f7 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 904b1d
index a1c1111..da2f428 100644
Mark McLoughlin 1c9931
--- a/net.c
Mark McLoughlin 1c9931
+++ b/net.c
Mark McLoughlin 904b1d
@@ -2559,7 +2559,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 904b1d
@@ -2629,6 +2629,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 904b1d
@@ -2645,13 +2646,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 904b1d
@@ -2998,8 +2999,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 904b1d
index 57ab031..94db0d7 100644
Mark McLoughlin 1c9931
--- a/net.h
Mark McLoughlin 1c9931
+++ b/net.h
Mark McLoughlin 904b1d
@@ -101,10 +101,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