[Libvir] PATCH: Avoid buffer out of bounds access in Xen capabilities

Daniel P. Berrange berrange at redhat.com
Mon Apr 28 22:42:47 UTC 2008


The Xen driver uses a regex to process the hypervisor capabilities data

  "(xen|hvm)-[[:digit:]]+\\.[[:digit:]]+-(x86_32|x86_64|ia64|powerpc64)(p|be)?";

notice how the last match group, however, is optional due to the '?'. The
code processing matches does not check to see if the match is present or
not, and just indexes the string on match 3

     if (strncmp (&token[subs[3].rm_so], "p", 1) == 0)

Unfortunately,  subs[3].rm_so is -1 if the match was not present, so we're
doing an out of bounds array access here. This is fairly harmless, but it
is still good to fix it. So this patch adds a check for -1 before accessing
the match. I also replace the strncmp() calls with a call to the brand new
STRPREFIX() convenience macro

Dan.

Index: src/xen_internal.c
===================================================================
RCS file: /data/cvs/libvirt/src/xen_internal.c,v
retrieving revision 1.119
diff -u -r1.119 xen_internal.c
--- src/xen_internal.c	10 Apr 2008 16:54:54 -0000	1.119
+++ src/xen_internal.c	28 Apr 2008 22:07:12 -0000
@@ -2349,28 +2349,31 @@
 
             if (regexec (&xen_cap_rec, token, sizeof subs / sizeof subs[0],
                          subs, 0) == 0) {
-                int hvm = strncmp (&token[subs[1].rm_so], "hvm", 3) == 0;
+                int hvm = STRPREFIX(&token[subs[1].rm_so], "hvm");
                 const char *model;
                 int bits, pae = 0, nonpae = 0, ia64_be = 0;
-                if (strncmp (&token[subs[2].rm_so], "x86_32", 6) == 0) {
+
+                if (STRPREFIX(&token[subs[2].rm_so], "x86_32")) {
                     model = "i686";
                     bits = 32;
-                    if (strncmp (&token[subs[3].rm_so], "p", 1) == 0)
+                    if (subs[3].rm_so != -1 &&
+                        STRPREFIX(&token[subs[3].rm_so], "p"))
                         pae = 1;
                     else
                         nonpae = 1;
                 }
-                else if (strncmp (&token[subs[2].rm_so], "x86_64", 6) == 0) {
+                else if (STRPREFIX(&token[subs[2].rm_so], "x86_64")) {
                     model = "x86_64";
                     bits = 64;
                 }
-                else if (strncmp (&token[subs[2].rm_so], "ia64", 4) == 0) {
+                else if (STRPREFIX(&token[subs[2].rm_so], "ia64")) {
                     model = "ia64";
                     bits = 64;
-                    if (strncmp (&token[subs[3].rm_so], "be", 2) == 0)
+                    if (subs[3].rm_so != -1 &&
+                        STRPREFIX(&token[subs[3].rm_so], "be"))
                         ia64_be = 1;
                 }
-                else if (strncmp (&token[subs[2].rm_so], "powerpc64", 4) == 0) {
+                else if (STRPREFIX(&token[subs[2].rm_so], "powerpc64")) {
                     model = "ppc64";
                     bits = 64;
                 } else {
@@ -2380,7 +2383,7 @@
 
                 /* Search for existing matching (model,hvm) tuple */
                 for (i = 0 ; i < nr_guest_archs ; i++) {
-                    if (!strcmp(guest_archs[i].model, model) &&
+                    if (STREQ(guest_archs[i].model, model) &&
                         guest_archs[i].hvm == hvm) {
                         break;
                     }

-- 
|: Red Hat, Engineering, Boston   -o-   http://people.redhat.com/berrange/ :|
|: http://libvirt.org  -o-  http://virt-manager.org  -o-  http://ovirt.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: GnuPG: 7D3B9505  -o-  F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|




More information about the libvir-list mailing list