You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
142 lines
5.3 KiB
142 lines
5.3 KiB
7 years ago
|
From 0a742856490bfdcb02c2af48a2a849593cccf1c7 Mon Sep 17 00:00:00 2001
|
||
|
From: Viktor Mihajlovski <mihajlov@linux.vnet.ibm.com>
|
||
|
Date: Thu, 29 Aug 2013 17:18:49 +0200
|
||
|
Subject: [PATCH 08/48] libxkutil: Improve domain.os_info cleanup
|
||
|
|
||
|
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@linux.vnet.ibm.com>
|
||
|
Signed-off-by: John Ferlan <jferlan@redhat.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 542e4e9..ad0f19c 100644
|
||
|
--- a/libxkutil/device_parsing.c
|
||
|
+++ b/libxkutil/device_parsing.c
|
||
|
@@ -1103,23 +1103,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;
|
||
|
|
||
|
@@ -1137,7 +1151,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")) &&
|
||
|
@@ -1154,17 +1168,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;
|
||
|
}
|
||
|
|
||
|
@@ -1360,15 +1396,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.8.5.3
|