]> git.ipfire.org Git - thirdparty/libvirt.git/commitdiff
openvz: avoid potential buffer overflow
authorEric Blake <eblake@redhat.com>
Tue, 7 Dec 2010 19:18:30 +0000 (12:18 -0700)
committerEric Blake <eblake@redhat.com>
Tue, 7 Dec 2010 22:40:01 +0000 (15:40 -0700)
* src/openvz/openvz_conf.c (openvzLoadDomains): Replace unsafe
sscanf with safe direct parsing.
(openvzGetVEID): Avoid lost integer overflow detection.
(openvzAssignUUIDs): Likewise, and detect readdir failure.

src/openvz/openvz_conf.c

index 800c1f4acf6efa299bdabb0e7ba42a8cd0e912da..a729f5919a22f2b4dc60616ce52e12f396b97a8c 100644 (file)
@@ -435,7 +435,7 @@ openvzFreeDriver(struct openvz_driver *driver)
 
 int openvzLoadDomains(struct openvz_driver *driver) {
     int veid, ret;
-    char status[16];
+    char *status;
     char uuidstr[VIR_UUID_STRING_BUFLEN];
     virDomainObjPtr dom = NULL;
     char temp[50];
@@ -451,13 +451,16 @@ int openvzLoadDomains(struct openvz_driver *driver) {
     if (virCommandRun(cmd, NULL) < 0)
         goto cleanup;
 
-    line = *outbuf ? outbuf : NULL;
-    while (line) {
-        if (sscanf(line, "%d %s\n", &veid, status) != 2) {
+    line = outbuf;
+    while (line[0] != '\0') {
+        if (virStrToLong_i(line, &status, 10, &veid) < 0 ||
+            *status++ != ' ' ||
+            (line = strchr(status, '\n')) == NULL) {
             openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
                         _("Failed to parse vzlist output"));
             goto cleanup;
         }
+        *line++ = '\0';
 
         if (VIR_ALLOC(dom) < 0)
             goto no_memory;
@@ -527,10 +530,6 @@ int openvzLoadDomains(struct openvz_driver *driver) {
 
         virDomainObjUnlock(dom);
         dom = NULL;
-
-        line = strchr(line, '\n');
-        if (line)
-            line++;
     }
 
     virCommandFree(cmd);
@@ -953,8 +952,9 @@ static int openvzAssignUUIDs(void)
     DIR *dp;
     struct dirent *dent;
     char *conf_dir;
-    int vpsid, res;
-    char ext[8];
+    int vpsid;
+    char *ext;
+    int ret = 0;
 
     conf_dir = openvzLocateConfDir();
     if (conf_dir == NULL)
@@ -966,16 +966,25 @@ static int openvzAssignUUIDs(void)
         return 0;
     }
 
+    errno = 0;
     while ((dent = readdir(dp))) {
-        res = sscanf(dent->d_name, "%d.%5s", &vpsid, ext);
-        if (!(res == 2 && STREQ(ext, "conf")))
+        if (virStrToLong_i(dent->d_name, &ext, 10, &vpsid) < 0 ||
+            *ext++ != '.' ||
+            STRNEQ(ext, "conf"))
             continue;
         if (vpsid > 0) /* '0.conf' belongs to the host, ignore it */
             openvzSetUUID(vpsid);
+        errno = 0;
+    }
+    if (errno) {
+        openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
+                    _("Failed to scan configuration directory"));
+        ret = -1;
     }
+
     closedir(dp);
     VIR_FREE(conf_dir);
-    return 0;
+    return ret;
 }
 
 
@@ -987,6 +996,7 @@ static int openvzAssignUUIDs(void)
 int openvzGetVEID(const char *name) {
     virCommandPtr cmd;
     char *outbuf;
+    char *temp;
     int veid;
     bool ok;
 
@@ -999,7 +1009,7 @@ int openvzGetVEID(const char *name) {
     }
 
     virCommandFree(cmd);
-    ok = sscanf(outbuf, "%d\n", &veid) == 1;
+    ok = virStrToLong_i(outbuf, &temp, 10, &veid) == 0 && *temp == '\n';
     VIR_FREE(outbuf);
 
     if (ok && veid >= 0)