Gianni Tedesco
2010-Dec-14 11:30 UTC
[Xen-devel] [PATCH]: xl: don''t segfault parsing disk configs, support NULL physpath and ioemu:
Resending due to another user reported running in to this. Applies with
offsets.
----------------8<--------------8<----------------
Switch to a state machine parser since it''s easier to handle all these
exotic cases without segfaulting. NULL physpaths are now allowed and a
dodgy hack is introduced to skip over the "ioemu:" prefix for a
virtpath. Also fixes a leak of buf2.
Signed-off-by: Gianni Tedesco <gianni.tedesco@citrix.com>
diff -r 6bd04080ab99 tools/libxl/xl_cmdimpl.c
--- a/tools/libxl/xl_cmdimpl.c Wed Aug 18 18:06:10 2010 +0100
+++ b/tools/libxl/xl_cmdimpl.c Thu Aug 19 15:34:20 2010 +0100
@@ -539,6 +539,134 @@ static int parse_action_on_shutdown(cons
return 0;
}
+#define DSTATE_INITIAL 0
+#define DSTATE_TAP 1
+#define DSTATE_PHYSPATH 2
+#define DSTATE_VIRTPATH 3
+#define DSTATE_VIRTTYPE 4
+#define DSTATE_RW 5
+#define DSTATE_TERMINAL 6
+
+static int parse_disk_config(libxl_device_disk *disk, char *buf2)
+{
+ int state = DSTATE_INITIAL;
+ char *p, *end, *tok;
+
+ memset(disk, 0, sizeof(*disk));
+
+ for(tok = p = buf2, end = buf2 + strlen(buf2) + 1; p < end; p++) {
+ switch(state){
+ case DSTATE_INITIAL:
+ if ( *p == '':'' ) {
+ *p = ''\0'';
+ if ( !strcmp(tok, "phy") ) {
+ state = DSTATE_PHYSPATH;
+ disk->phystype = PHYSTYPE_PHY;
+ }else if ( !strcmp(tok, "file") ) {
+ state = DSTATE_PHYSPATH;
+ disk->phystype = PHYSTYPE_FILE;
+ }else if ( !strcmp(tok, "tap") ) {
+ state = DSTATE_TAP;
+ }else{
+ fprintf(stderr, "Unknown disk type: %s\n", tok);
+ return 0;
+ }
+ tok = p + 1;
+ }
+ break;
+ case DSTATE_TAP:
+ if ( *p == '':'' ) {
+ *p = ''\0'';
+ if ( !strcmp(tok, "aio") ) {
+ disk->phystype = PHYSTYPE_AIO;
+ }else if ( !strcmp(tok, "vhd") ) {
+ disk->phystype = PHYSTYPE_VHD;
+ }else if ( !strcmp(tok, "qcow") ) {
+ disk->phystype = PHYSTYPE_QCOW;
+ }else if ( !strcmp(tok, "qcow2") ) {
+ disk->phystype = PHYSTYPE_QCOW2;
+ }else {
+ fprintf(stderr, "Unknown tapdisk type: %s\n",
tok);
+ return 0;
+ }
+
+ tok = p + 1;
+ state = DSTATE_PHYSPATH;
+ }
+ break;
+ case DSTATE_PHYSPATH:
+ if ( *p == '','' ) {
+ int ioemu_len;
+
+ *p = ''\0'';
+ disk->physpath = (*tok) ? strdup(tok) : NULL;
+ tok = p + 1;
+
+ /* hack for ioemu disk spec */
+ ioemu_len = strlen("ioemu:");
+ state = DSTATE_VIRTPATH;
+ if ( tok + ioemu_len < end &&
+ !strncmp(tok, "ioemu:", ioemu_len)) {
+ tok += ioemu_len;
+ p += ioemu_len;
+ }
+ }
+ break;
+ case DSTATE_VIRTPATH:
+ if ( *p == '','' || *p == '':'' ||
*p == ''\0'' ) {
+ switch(*p) {
+ case '':'':
+ state = DSTATE_VIRTTYPE;
+ break;
+ case '','':
+ state = DSTATE_RW;
+ break;
+ case ''\0'':
+ state = DSTATE_TERMINAL;
+ break;
+ }
+ if ( tok == p )
+ goto out;
+ *p = ''\0'';
+ disk->virtpath = (*tok) ? strdup(tok) : NULL;
+ tok = p + 1;
+ }
+ break;
+ case DSTATE_VIRTTYPE:
+ if ( *p == '','' || *p == ''\0'' )
{
+ *p = ''\0'';
+ if ( !strcmp(tok, "cdrom") ) {
+ disk->is_cdrom = 1;
+ disk->unpluggable = 1;
+ }else{
+ fprintf(stderr, "Unknown virtual disk type:
%s\n", tok);
+ return 0;
+ }
+ tok = p + 1;
+ state = (*p == '','') ? DSTATE_RW :
DSTATE_TERMINAL;
+ }
+ break;
+ case DSTATE_RW:
+ if ( *p == ''\0'' ) {
+ disk->readwrite = (tok[0] == ''w'');
+ tok = p + 1;
+ state = DSTATE_TERMINAL;
+ }
+ break;
+ case DSTATE_TERMINAL:
+ goto out;
+ }
+ }
+
+out:
+ if ( tok != p || state != DSTATE_TERMINAL ) {
+ fprintf(stderr, "parse error in disk config near
''%s''\n", tok);
+ return 0;
+ }
+
+ return 1;
+}
+
static void parse_config_data(const char *configfile_filename_report,
const char *configfile_data,
int configfile_len,
@@ -716,59 +844,13 @@ static void parse_config_data(const char
while ((buf = xlu_cfg_get_listitem (vbds, d_config->num_disks)) !=
NULL) {
libxl_device_disk *disk;
char *buf2 = strdup(buf);
- char *p, *p2;
d_config->disks = (libxl_device_disk *)
realloc(d_config->disks, sizeof (libxl_device_disk) * (d_config->num_disks
+ 1));
disk = d_config->disks + d_config->num_disks;
-
- disk->backend_domid = 0;
- disk->domid = 0;
- disk->unpluggable = 0;
-
- p = strtok(buf2, ",:");
- while (*p == '' '')
- p++;
- if (!strcmp(p, "phy")) {
- disk->phystype = PHYSTYPE_PHY;
- } else if (!strcmp(p, "file")) {
- disk->phystype = PHYSTYPE_FILE;
- } else if (!strcmp(p, "tap")) {
- p = strtok(NULL, ":");
- if (!strcmp(p, "aio")) {
- disk->phystype = PHYSTYPE_AIO;
- } else if (!strcmp(p, "vhd")) {
- disk->phystype = PHYSTYPE_VHD;
- } else if (!strcmp(p, "qcow")) {
- disk->phystype = PHYSTYPE_QCOW;
- } else if (!strcmp(p, "qcow2")) {
- disk->phystype = PHYSTYPE_QCOW2;
- }
+ if ( !parse_disk_config(disk, buf2) ) {
+ exit(1);
}
- p = strtok(NULL, ",");
- while (*p == '' '')
- p++;
- disk->physpath= strdup(p);
- p = strtok(NULL, ",");
- while (*p == '' '')
- p++;
- p2 = strchr(p, '':'');
- if (p2 == NULL) {
- disk->virtpath = strdup(p);
- disk->is_cdrom = 0;
- disk->unpluggable = 1;
- } else {
- *p2 = ''\0'';
- disk->virtpath = strdup(p);
- if (!strcmp(p2 + 1, "cdrom")) {
- disk->is_cdrom = 1;
- disk->unpluggable = 1;
- } else
- disk->is_cdrom = 0;
- }
- p = strtok(NULL, ",");
- while (*p == '' '')
- p++;
- disk->readwrite = (p[0] == ''w'') ? 1 : 0;
+
free(buf2);
d_config->num_disks++;
}
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Ian Jackson
2010-Dec-14 17:40 UTC
Re: [Xen-devel] [PATCH]: xl: don''t segfault parsing disk configs, support NULL physpath and ioemu:
Gianni Tedesco writes ("[Xen-devel] [PATCH]: xl: don''t segfault
parsing disk configs, support NULL physpath and
ioemu:"):> Resending due to another user reported running in to this. Applies with
> offsets.
...> Switch to a state machine parser since it''s easier to handle all
these
> exotic cases without segfaulting. NULL physpaths are now allowed and a
> dodgy hack is introduced to skip over the "ioemu:" prefix for a
> virtpath. Also fixes a leak of buf2.
Thanks, but I think the last time we had this we had some negative
feedback about the comprehensibility of this approach.
Perhaps a regexp- or flex- or bison- based approach would be better ?
Ian.
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel
Gianni Tedesco
2010-Dec-14 18:21 UTC
Re: [Xen-devel] [PATCH]: xl: don''t segfault parsing disk configs, support NULL physpath and ioemu:
On Tue, 2010-12-14 at 17:40 +0000, Ian Jackson wrote:> Gianni Tedesco writes ("[Xen-devel] [PATCH]: xl: don''t segfault parsing disk configs, support NULL physpath and ioemu:"): > > Resending due to another user reported running in to this. Applies with > > offsets. > ... > > Switch to a state machine parser since it''s easier to handle all these > > exotic cases without segfaulting. NULL physpaths are now allowed and a > > dodgy hack is introduced to skip over the "ioemu:" prefix for a > > virtpath. Also fixes a leak of buf2. > > Thanks, but I think the last time we had this we had some negative > feedback about the comprehensibility of this approach.Yes... from you :)> Perhaps a regexp- or flex- or bison- based approach would be better ?ISTR you said you''d do it in flex but since: 1. people are running to the bugs "out in the world" 2. we have an existing fix 3. I have no flex-fu 4. and we were in agreement that this code is as readable or more-so than a correct strtok-based implementation then why not take the fix we have now and improve if/when we need to in the future? Evidently nobody has touched this code for 6 months or more.> Ian.Gianni _______________________________________________ Xen-devel mailing list Xen-devel@lists.xensource.com http://lists.xensource.com/xen-devel
Ian Jackson
2011-Jan-05 23:13 UTC
Re: [Xen-devel] [PATCH]: xl: don''t segfault parsing disk configs, support NULL physpath and ioemu:
Gianni Tedesco writes ("[Xen-devel] [PATCH]: xl: don''t segfault
parsing disk configs, support NULL physpath and
ioemu:"):> Resending due to another user reported running in to this. Applies with
> offsets.
I''ve applied this, thanks.
Ian.
_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xensource.com
http://lists.xensource.com/xen-devel