WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [PATCH]: xl: introduce xlu_cfg_get_(string|long)_default

To: Xen Devel <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [PATCH]: xl: introduce xlu_cfg_get_(string|long)_default
From: Gianni Tedesco <gianni.tedesco@xxxxxxxxxx>
Date: Tue, 31 Aug 2010 16:42:33 +0100
Cc: Ian Campbell <Ian.Campbell@xxxxxxxxxxxxx>, Ian Jackson <Ian.Jackson@xxxxxxxxxxxxx>, Stefano Stabellini <stefano.stabellini@xxxxxxxxxxxxx>
Delivery-date: Tue, 31 Aug 2010 08:46:41 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
The function init_dm_info() in xl_cmdimpl.c is used to initialise a
libxl_device_model_info structure with some default values. After being
called, some of those values are overridden. For the string values which
are not overwritten we either end up with a double free or attempt to
free a string literal resulting in a segfault. This type of usage model
would be complex to fix by adding strdup()'s in the init function and
then checking and freeing when over-writing.

My proposed solution is to add default versions of xlu_cfg_get_string
and xlu_cfg_get_long. This way both double-free's and leaks are avoided
and arguably the intention of the code is clearer.

Signed-off-by: Gianni Tedesco <gianni.tedesco@xxxxxxxxxx>

diff -r d323c34ec982 -r aa90461b1d04 tools/libxl/libxlu_cfg.c
--- a/tools/libxl/libxlu_cfg.c  Tue Aug 31 13:30:21 2010 +0100
+++ b/tools/libxl/libxlu_cfg.c  Tue Aug 31 14:01:07 2010 +0100
@@ -151,7 +151,23 @@ int xlu_cfg_get_string(const XLU_Config 
     *value_r= set->values[0];
     return 0;
 }
-        
+
+int xlu_cfg_get_string_default(const XLU_Config *cfg, const char *n,
+                       const char **value_r, const char *def) {
+    XLU_ConfigSetting *set;
+    int e;
+
+    e= find_atom(cfg,n,&set);
+    if (e) {
+        *value_r = strdup(def);
+        if ( def && NULL == *value_r )
+            return ENOMEM;
+        return 0;
+    }
+    *value_r= set->values[0];
+    return 0;
+}
+
 int xlu_cfg_get_long(const XLU_Config *cfg, const char *n,
                      long *value_r) {
     long l;
@@ -181,6 +197,35 @@ int xlu_cfg_get_long(const XLU_Config *c
     return 0;
 }
         
+int xlu_cfg_get_long_default(const XLU_Config *cfg, const char *n,
+                     long *value_r, long def) {
+    long l;
+    XLU_ConfigSetting *set;
+    int e;
+    char *ep;
+
+    e= find_atom(cfg,n,&set);  if (e) { *value_r = def; return 0; }
+    errno= 0; l= strtol(set->values[0], &ep, 0);
+    e= errno;
+    if (errno) {
+        e= errno;
+        assert(e==EINVAL || e==ERANGE);
+        fprintf(cfg->report,
+                "%s:%d: warning: parameter `%s' could not be parsed"
+                " as a number: %s\n",
+                cfg->filename, set->lineno, n, strerror(e));
+        *value_r = def;
+        return e;
+    }
+    if (*ep || ep==set->values[0]) {
+        fprintf(cfg->report,
+                "%s:%d: warning: parameter `%s' is not a valid number\n",
+                cfg->filename, set->lineno, n);
+        return EINVAL;
+    }
+    *value_r= l;
+    return 0;
+}
 
 int xlu_cfg_get_list(const XLU_Config *cfg, const char *n,
                      XLU_ConfigList **list_r, int *entries_r) {
diff -r d323c34ec982 -r aa90461b1d04 tools/libxl/libxlutil.h
--- a/tools/libxl/libxlutil.h   Tue Aug 31 13:30:21 2010 +0100
+++ b/tools/libxl/libxlutil.h   Tue Aug 31 14:01:07 2010 +0100
@@ -46,7 +46,10 @@ void xlu_cfg_destroy(XLU_Config*);
  */
 
 int xlu_cfg_get_string(const XLU_Config*, const char *n, const char **value_r);
+int xlu_cfg_get_string_default(const XLU_Config *cfg, const char *n,
+                                const char **value_r, const char *def);
 int xlu_cfg_get_long(const XLU_Config*, const char *n, long *value_r);
+int xlu_cfg_get_long_default(const XLU_Config*, const char *n, long *value_r, 
long def);
 
 int xlu_cfg_get_list(const XLU_Config*, const char *n,
                      XLU_ConfigList **list_r /* may be 0 */,
diff -r d323c34ec982 -r aa90461b1d04 tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c  Tue Aug 31 13:30:21 2010 +0100
+++ b/tools/libxl/xl_cmdimpl.c  Tue Aug 31 14:01:07 2010 +0100
@@ -286,36 +286,6 @@ static void init_build_info(libxl_domain
     }
 }
 
-static void init_dm_info(libxl_device_model_info *dm_info,
-        libxl_domain_create_info *c_info, libxl_domain_build_info *b_info)
-{
-    memset(dm_info, '\0', sizeof(*dm_info));
-
-    libxl_uuid_generate(&dm_info->uuid);
-
-    dm_info->dom_name = c_info->name;
-    dm_info->device_model = "qemu-dm";
-    dm_info->videoram = b_info->video_memkb / 1024;
-    dm_info->apic = b_info->u.hvm.apic;
-    dm_info->vcpus = b_info->max_vcpus;
-    dm_info->vcpu_avail = b_info->cur_vcpus;
-
-    dm_info->stdvga = 0;
-    dm_info->vnc = 1;
-    dm_info->vnclisten = "127.0.0.1";
-    dm_info->vncdisplay = 0;
-    dm_info->vncunused = 1;
-    dm_info->keymap = NULL;
-    dm_info->sdl = 0;
-    dm_info->opengl = 0;
-    dm_info->nographic = 0;
-    dm_info->serial = NULL;
-    dm_info->boot = "cda";
-    dm_info->usb = 0;
-    dm_info->usbdevice = NULL;
-    dm_info->xen_platform_pci = 1;
-}
-
 static void init_nic_info(libxl_device_nic *nic_info, int devnum)
 {
     const uint8_t *r;
@@ -1008,22 +978,31 @@ skip_vfb:
 
     if (c_info->hvm == 1) {
         /* init dm from c and b */
-        init_dm_info(dm_info, c_info, b_info);
+        memset(dm_info, '\0', sizeof(*dm_info));
+
+        libxl_uuid_generate(&dm_info->uuid);
+        dm_info->dom_name = strdup(c_info->name);
+
+        dm_info->videoram = b_info->video_memkb / 1024;
+        dm_info->apic = b_info->u.hvm.apic;
+        dm_info->vcpus = b_info->max_vcpus;
+        dm_info->vcpu_avail = b_info->cur_vcpus;
 
         /* then process config related to dm */
-        if (!xlu_cfg_get_string (config, "device_model", &buf))
+        if (!xlu_cfg_get_string_default (config, "device_model", &buf, 
"qemu-dm"))
             dm_info->device_model = strdup(buf);
+
         if (!xlu_cfg_get_long (config, "stdvga", &l))
             dm_info->stdvga = l;
-        if (!xlu_cfg_get_long (config, "vnc", &l))
+        if (!xlu_cfg_get_long_default (config, "vnc", &l, 1))
             dm_info->vnc = l;
-        if (!xlu_cfg_get_string (config, "vnclisten", &buf))
+        if (!xlu_cfg_get_string_default (config, "vnclisten", &buf, 
"127.0.0.1"))
             dm_info->vnclisten = strdup(buf);
         if (!xlu_cfg_get_string (config, "vncpasswd", &buf))
             dm_info->vncpasswd = strdup(buf);
         if (!xlu_cfg_get_long (config, "vncdisplay", &l))
             dm_info->vncdisplay = l;
-        if (!xlu_cfg_get_long (config, "vncunused", &l))
+        if (!xlu_cfg_get_long_default (config, "vncunused", &l, 1))
             dm_info->vncunused = l;
         if (!xlu_cfg_get_string (config, "keymap", &buf))
             dm_info->keymap = strdup(buf);
@@ -1035,7 +1014,7 @@ skip_vfb:
             dm_info->nographic = l;
         if (!xlu_cfg_get_string (config, "serial", &buf))
             dm_info->serial = strdup(buf);
-        if (!xlu_cfg_get_string (config, "boot", &buf))
+        if (!xlu_cfg_get_string_default (config, "boot", &buf, "cda"))
             dm_info->boot = strdup(buf);
         if (!xlu_cfg_get_long (config, "usb", &l))
             dm_info->usb = l;
@@ -1043,7 +1022,7 @@ skip_vfb:
             dm_info->usbdevice = strdup(buf);
         if (!xlu_cfg_get_string (config, "soundhw", &buf))
             dm_info->soundhw = strdup(buf);
-        if (!xlu_cfg_get_long (config, "xen_platform_pci", &l))
+        if (!xlu_cfg_get_long_default (config, "xen_platform_pci", &l, 1))
             dm_info->xen_platform_pci = l;
     }
 



_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel