[Libvirt-cim] [PATCHv2 1/5] libxkutil: Improve domain.os_info cleanup

Viktor Mihajlovski mihajlov at linux.vnet.ibm.com
Thu Aug 29 15:18:49 UTC 2013


The union fields in os_info were set by means of XML parsing which
doesn't take into account that certain fields are depending on the
virtualization type.
This could lead both to memory overwrites and memory leaks.
Fixed by using temporary variables and type-based setting of fields

Signed-off-by: Viktor Mihajlovski <mihajlov at linux.vnet.ibm.com>
---
 libxkutil/device_parsing.c |   73 +++++++++++++++++++++++++++++++-------------
 1 file changed, 52 insertions(+), 21 deletions(-)

diff --git a/libxkutil/device_parsing.c b/libxkutil/device_parsing.c
index ffdf682..500c724 100644
--- a/libxkutil/device_parsing.c
+++ b/libxkutil/device_parsing.c
@@ -1077,23 +1077,37 @@ int parse_fq_devid(const char *devid, char **host, char **device)
         return 1;
 }
 
+static void cleanup_bootlist(char **blist, unsigned blist_ct)
+{
+        while (blist_ct > 0) {
+                free(blist[--blist_ct]);
+        }
+        free(blist);
+}
+
 static int parse_os(struct domain *dominfo, xmlNode *os)
 {
         xmlNode *child;
         char **blist = NULL;
         unsigned bl_size = 0;
+        char *kernel = NULL;
+        char *initrd = NULL;
+        char *cmdline = NULL;
+        char *loader = NULL;
+        char *boot = NULL;
+        char *init = NULL;
 
         for (child = os->children; child != NULL; child = child->next) {
-                if (XSTREQ(child->name, "type"))
+                if (XSTREQ(child->name, "type")) {
                         STRPROP(dominfo, os_info.pv.type, child);
-                else if (XSTREQ(child->name, "kernel"))
-                        STRPROP(dominfo, os_info.pv.kernel, child);
+                } else if (XSTREQ(child->name, "kernel"))
+                        kernel = get_node_content(child);
                 else if (XSTREQ(child->name, "initrd"))
-                        STRPROP(dominfo, os_info.pv.initrd, child);
+                        initrd = get_node_content(child);
                 else if (XSTREQ(child->name, "cmdline"))
-                        STRPROP(dominfo, os_info.pv.cmdline, child);
+                        cmdline = get_node_content(child);
                 else if (XSTREQ(child->name, "loader"))
-                        STRPROP(dominfo, os_info.fv.loader, child);
+                        loader = get_node_content(child);
                 else if (XSTREQ(child->name, "boot")) {
                         char **tmp_list = NULL;
 
@@ -1111,7 +1125,7 @@ static int parse_os(struct domain *dominfo, xmlNode *os)
                         blist[bl_size] = get_attr_value(child, "dev");
                         bl_size++;
                 } else if (XSTREQ(child->name, "init"))
-                        STRPROP(dominfo, os_info.lxc.init, child);
+                        init = get_node_content(child);
         }
 
         if ((STREQC(dominfo->os_info.fv.type, "hvm")) &&
@@ -1128,17 +1142,39 @@ static int parse_os(struct domain *dominfo, xmlNode *os)
         else
                 dominfo->type = -1;
 
-        if (STREQC(dominfo->os_info.fv.type, "hvm")) {
+        switch (dominfo->type) {
+        case DOMAIN_XENFV:
+        case DOMAIN_KVM:
+        case DOMAIN_QEMU:
+                dominfo->os_info.fv.loader = loader;
                 dominfo->os_info.fv.bootlist_ct = bl_size;
                 dominfo->os_info.fv.bootlist = blist;
-        } else {
-            int i;
-
-            for (i = 0; i < bl_size; i++)
-                free(blist[i]);
-            free(blist);
+                loader = NULL;
+                blist = NULL;
+                bl_size = 0;
+                break;
+        case DOMAIN_XENPV:
+                dominfo->os_info.pv.kernel = kernel;
+                dominfo->os_info.pv.initrd = initrd;
+                dominfo->os_info.pv.cmdline = cmdline;
+                kernel = NULL;
+                initrd = NULL;
+                cmdline = NULL;
+                break;
+        case DOMAIN_LXC:
+                dominfo->os_info.lxc.init = init;
+                init = NULL;
+                break;
+        default:
+                break;
         }
 
+        free(kernel);
+        free(initrd);
+        free(cmdline);
+        free(boot);
+        free(init);
+        cleanup_bootlist(blist, bl_size);
         return 1;
 }
 
@@ -1334,15 +1370,10 @@ void cleanup_dominfo(struct domain **dominfo)
                 free(dom->os_info.pv.cmdline);
         } else if ((dom->type == DOMAIN_XENFV) ||
                    (dom->type == DOMAIN_KVM) || (dom->type == DOMAIN_QEMU)) {
-                int i;
-
                 free(dom->os_info.fv.type);
                 free(dom->os_info.fv.loader);
-                
-                for (i = 0; i < dom->os_info.fv.bootlist_ct; i++) {
-                        free(dom->os_info.fv.bootlist[i]);
-                } 
-                free(dom->os_info.fv.bootlist);
+                cleanup_bootlist(dom->os_info.fv.bootlist,
+                                 dom->os_info.fv.bootlist_ct);
         } else if (dom->type == DOMAIN_LXC) {
                 free(dom->os_info.lxc.type);
                 free(dom->os_info.lxc.init);
-- 
1.7.9.5




More information about the Libvirt-cim mailing list