[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-devel] [PATCH]: xl: introduce xlu_cfg_get_(string|long)_default
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
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |