openvz: avoid potential buffer overflow

* 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.
This commit is contained in:
Eric Blake 2010-12-07 12:18:30 -07:00
parent bfd6267bcd
commit a0ac00f4f0

View 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)