Replace openvz_readline with getline in several places to get rid of stack allocated buffers to hold lines. openvzReadConfigParam allocates memory for return values instead of expecting a preexisting buffer. --- src/openvz/openvz_conf.c | 141 +++++++++++++++++++++++++++----------------- src/openvz/openvz_conf.h | 2 +- src/openvz/openvz_driver.c | 45 +++++++++----- 3 files changed, 117 insertions(+), 71 deletions(-) diff --git a/src/openvz/openvz_conf.c b/src/openvz/openvz_conf.c index 2fcca68..88cd4c8 100644 --- a/src/openvz/openvz_conf.c +++ b/src/openvz/openvz_conf.c @@ -187,7 +187,7 @@ openvzReadNetworkConf(virDomainDefPtr def, int veid) { int ret; virDomainNetDefPtr net = NULL; - char temp[4096]; + char *temp = NULL; char *token, *saveptr = NULL; /*parse routing network configuration* @@ -195,7 +195,7 @@ openvzReadNetworkConf(virDomainDefPtr def, * IP_ADDRESS="1.1.1.1 1.1.1.2" * splited IPs by space */ - ret = openvzReadVPSConfigParam(veid, "IP_ADDRESS", temp, sizeof(temp)); + ret = openvzReadVPSConfigParam(veid, "IP_ADDRESS", &temp); if (ret < 0) { openvzError(VIR_ERR_INTERNAL_ERROR, _("Could not read 'IP_ADDRESS' from config for container %d"), @@ -227,7 +227,7 @@ openvzReadNetworkConf(virDomainDefPtr def, *NETIF="ifname=eth10,mac=00:18:51:C1:05:EE,host_ifname=veth105.10,host_mac=00:18:51:8F:D9:F3" *devices splited by ';' */ - ret = openvzReadVPSConfigParam(veid, "NETIF", temp, sizeof(temp)); + ret = openvzReadVPSConfigParam(veid, "NETIF", &temp); if (ret < 0) { openvzError(VIR_ERR_INTERNAL_ERROR, _("Could not read 'NETIF' from config for container %d"), @@ -316,10 +316,13 @@ openvzReadNetworkConf(virDomainDefPtr def, } } + VIR_FREE(temp); + return 0; no_memory: virReportOOMError(); error: + VIR_FREE(temp); virDomainNetDefFree(net); return -1; } @@ -364,10 +367,10 @@ openvzReadFSConf(virDomainDefPtr def, int veid) { int ret; virDomainFSDefPtr fs = NULL; - char* veid_str = NULL; - char temp[100]; + char *veid_str = NULL; + char *temp = NULL; - ret = openvzReadVPSConfigParam(veid, "OSTEMPLATE", temp, sizeof(temp)); + ret = openvzReadVPSConfigParam(veid, "OSTEMPLATE", &temp); if (ret < 0) { openvzError(VIR_ERR_INTERNAL_ERROR, _("Could not read 'OSTEMPLATE' from config for container %d"), @@ -381,7 +384,7 @@ openvzReadFSConf(virDomainDefPtr def, fs->src = strdup(temp); } else { /* OSTEMPLATE was not found, VE was booted from a private dir directly */ - ret = openvzReadVPSConfigParam(veid, "VE_PRIVATE", temp, sizeof(temp)); + ret = openvzReadVPSConfigParam(veid, "VE_PRIVATE", &temp); if (ret <= 0) { openvzError(VIR_ERR_INTERNAL_ERROR, _("Could not read 'VE_PRIVATE' from config for container %d"), @@ -411,10 +414,13 @@ openvzReadFSConf(virDomainDefPtr def, def->fss[def->nfss++] = fs; fs = NULL; + VIR_FREE(temp); + return 0; no_memory: virReportOOMError(); error: + VIR_FREE(temp); virDomainFSDefFree(fs); return -1; } @@ -439,7 +445,7 @@ int openvzLoadDomains(struct openvz_driver *driver) { char *status; char uuidstr[VIR_UUID_STRING_BUFLEN]; virDomainObjPtr dom = NULL; - char temp[50]; + char *temp = NULL; char *outbuf = NULL; char *line; virCommandPtr cmd = NULL; @@ -506,7 +512,7 @@ int openvzLoadDomains(struct openvz_driver *driver) { if (!(dom->def->os.init = strdup("/sbin/init"))) goto no_memory; - ret = openvzReadVPSConfigParam(veid, "CPUS", temp, sizeof(temp)); + ret = openvzReadVPSConfigParam(veid, "CPUS", &temp); if (ret < 0) { openvzError(VIR_ERR_INTERNAL_ERROR, _("Could not read config for container %d"), @@ -534,6 +540,7 @@ int openvzLoadDomains(struct openvz_driver *driver) { } virCommandFree(cmd); + VIR_FREE(temp); VIR_FREE(outbuf); return 0; @@ -543,6 +550,7 @@ int openvzLoadDomains(struct openvz_driver *driver) { cleanup: virCommandFree(cmd); + VIR_FREE(temp); VIR_FREE(outbuf); /* dom hasn't been shared yet, so unref should return 0 */ if (dom) @@ -565,25 +573,26 @@ static int openvzWriteConfigParam(const char * conf_file, const char *param, const char *value) { char * temp_file = NULL; - int fd = -1, temp_fd = -1; - char line[PATH_MAX]; + int temp_fd = -1; + FILE *fp; + char *line = NULL; + size_t line_size = 0; if (virAsprintf(&temp_file, "%s.tmp", conf_file)<0) { virReportOOMError(); return -1; } - fd = open(conf_file, O_RDONLY); - if (fd == -1) + fp = fopen(conf_file, "r"); + if (fp == NULL) goto error; temp_fd = open(temp_file, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (temp_fd == -1) { - VIR_FORCE_CLOSE(fd); goto error; } while (1) { - if (openvz_readline(fd, line, sizeof(line)) <= 0) + if (getline(&line, &line_size, fp) <= 0) break; if (!(STRPREFIX(line, param) && line[strlen(param)] == '=')) { @@ -599,7 +608,7 @@ openvzWriteConfigParam(const char * conf_file, const char *param, const char *va safewrite(temp_fd, "\"\n", 2) < 0) goto error; - if (VIR_CLOSE(fd) < 0) + if (VIR_FCLOSE(fp) < 0) goto error; if (VIR_CLOSE(temp_fd) < 0) goto error; @@ -607,10 +616,13 @@ openvzWriteConfigParam(const char * conf_file, const char *param, const char *va if (rename(temp_file, conf_file) < 0) goto error; + VIR_FREE(line); + return 0; error: - VIR_FORCE_CLOSE(fd); + VIR_FREE(line); + VIR_FORCE_FCLOSE(fp); VIR_FORCE_CLOSE(temp_fd); if (temp_file) unlink(temp_file); @@ -632,23 +644,29 @@ openvzWriteVPSConfigParam(int vpsid, const char *param, const char *value) return ret; } +/* + * value will be freed before a new value is assigned to it, the caller is + * responsible for freeing it afterwards. + */ static int -openvzReadConfigParam(const char * conf_file ,const char * param, char *value, int maxlen) +openvzReadConfigParam(const char *conf_file, const char *param, char **value) { - char line[PATH_MAX]; - int ret, found = 0; - int fd; - char * sf, * token; + char *line = NULL; + size_t line_size = 0; + ssize_t ret; + FILE *fp; + int found = 0; + char *sf, *token; char *saveptr = NULL; value[0] = 0; - fd = open(conf_file, O_RDONLY); - if (fd == -1) + fp = fopen(conf_file, "r"); + if (fp == NULL) return -1; while (1) { - ret = openvz_readline(fd, line, sizeof(line)); + ret = getline(&line, &line_size, fp); if (ret <= 0) break; saveptr = NULL; @@ -658,7 +676,9 @@ openvzReadConfigParam(const char * conf_file ,const char * param, char *value, i if (sf[0] == '=' && sf[1] != '\0' ) { sf++; if ((token = strtok_r(sf,"\"\t\n", &saveptr)) != NULL) { - if (virStrcpy(value, token, maxlen) == NULL) { + VIR_FREE(*value); + *value = strdup(token); + if (value == NULL) { ret = -1; break; } @@ -667,7 +687,8 @@ openvzReadConfigParam(const char * conf_file ,const char * param, char *value, i } } } - VIR_FORCE_CLOSE(fd); + VIR_FREE(line); + VIR_FORCE_FCLOSE(fp); if (ret == 0 && found) ret = 1; @@ -676,14 +697,18 @@ openvzReadConfigParam(const char * conf_file ,const char * param, char *value, i } /* -* Read parameter from container config -* sample: 133, "OSTEMPLATE", value, 1024 -* return: -1 - error -* 0 - don't found -* 1 - OK -*/ + * Read parameter from container config + * + * value will be freed before a new value is assined to it, the caller is + * responsible for freeing it afterwards. + * + * sample: 133, "OSTEMPLATE", &value + * return: -1 - error + * 0 - don't found + * 1 - OK + */ int -openvzReadVPSConfigParam(int vpsid ,const char * param, char *value, int maxlen) +openvzReadVPSConfigParam(int vpsid, const char *param, char **value) { char *conf_file; int ret; @@ -691,7 +716,7 @@ openvzReadVPSConfigParam(int vpsid ,const char * param, char *value, int maxlen) if (openvzLocateConfFile(vpsid, &conf_file, "conf") < 0) return -1; - ret = openvzReadConfigParam(conf_file, param, value, maxlen); + ret = openvzReadConfigParam(conf_file, param, value); VIR_FREE(conf_file); return ret; } @@ -699,21 +724,23 @@ openvzReadVPSConfigParam(int vpsid ,const char * param, char *value, int maxlen) static int openvz_copyfile(char* from_path, char* to_path) { - char line[PATH_MAX]; - int fd, copy_fd; + char *line = NULL; + size_t line_size = 0; + FILE *fp; + int copy_fd; int bytes_read; - fd = open(from_path, O_RDONLY); - if (fd == -1) + fp = fopen(from_path, "r"); + if (fp == NULL) return -1; copy_fd = open(to_path, O_WRONLY | O_CREAT | O_TRUNC, 0644); if (copy_fd == -1) { - VIR_FORCE_CLOSE(fd); + VIR_FORCE_FCLOSE(fp); return -1; } while (1) { - if (openvz_readline(fd, line, sizeof(line)) <= 0) + if (getline(&line, &line_size, fp) <= 0) break; bytes_read = strlen(line); @@ -721,15 +748,18 @@ openvz_copyfile(char* from_path, char* to_path) goto error; } - if (VIR_CLOSE(fd) < 0) + if (VIR_FCLOSE(fp) < 0) goto error; if (VIR_CLOSE(copy_fd) < 0) goto error; + VIR_FREE(line); + return 0; error: - VIR_FORCE_CLOSE(fd); + VIR_FREE(line); + VIR_FORCE_FCLOSE(fp); VIR_FORCE_CLOSE(copy_fd); return -1; } @@ -742,14 +772,13 @@ error: int openvzCopyDefaultConfig(int vpsid) { - char * confdir = NULL; - char * default_conf_file = NULL; - char configfile_value[PATH_MAX]; + char *confdir = NULL; + char *default_conf_file = NULL; + char *configfile_value = NULL; char *conf_file = NULL; int ret = -1; - if (openvzReadConfigParam(VZ_CONF_FILE, "CONFIGFILE", configfile_value, - PATH_MAX) < 0) + if (openvzReadConfigParam(VZ_CONF_FILE, "CONFIGFILE", &configfile_value) < 0) goto cleanup; confdir = openvzLocateConfDir(); @@ -772,6 +801,7 @@ openvzCopyDefaultConfig(int vpsid) cleanup: VIR_FREE(confdir); VIR_FREE(default_conf_file); + VIR_FREE(configfile_value); VIR_FREE(conf_file); return ret; } @@ -844,22 +874,24 @@ static int openvzGetVPSUUID(int vpsid, char *uuidstr, size_t len) { char *conf_file; - char line[1024]; + char *line = NULL; + size_t line_size = 0; + ssize_t ret; char *saveptr = NULL; char *uuidbuf; char *iden; - int fd, ret; + FILE *fp; int retval = -1; if (openvzLocateConfFile(vpsid, &conf_file, "conf") < 0) return -1; - fd = open(conf_file, O_RDONLY); - if (fd == -1) + fp = fopen(conf_file, "r"); + if (fp == NULL) goto cleanup; while (1) { - ret = openvz_readline(fd, line, sizeof(line)); + ret = getline(&line, &line_size, fp); if (ret == -1) goto cleanup; @@ -882,7 +914,8 @@ openvzGetVPSUUID(int vpsid, char *uuidstr, size_t len) } retval = 0; cleanup: - VIR_FORCE_CLOSE(fd); + VIR_FREE(line); + VIR_FORCE_FCLOSE(fp); VIR_FREE(conf_file); return retval; diff --git a/src/openvz/openvz_conf.h b/src/openvz/openvz_conf.h index 50bcb5e..4673fa6 100644 --- a/src/openvz/openvz_conf.h +++ b/src/openvz/openvz_conf.h @@ -55,7 +55,7 @@ struct openvz_driver { int openvz_readline(int fd, char *ptr, int maxlen); int openvzExtractVersion(struct openvz_driver *driver); -int openvzReadVPSConfigParam(int vpsid ,const char * param, char *value, int maxlen); +int openvzReadVPSConfigParam(int vpsid, const char *param, char **value); int openvzWriteVPSConfigParam(int vpsid, const char *param, const char *value); int openvzCopyDefaultConfig(int vpsid); virCapsPtr openvzCapsInit(void); diff --git a/src/openvz/openvz_driver.c b/src/openvz/openvz_driver.c index fb30c37..c6fee3b 100644 --- a/src/openvz/openvz_driver.c +++ b/src/openvz/openvz_driver.c @@ -631,15 +631,16 @@ openvzGenerateVethName(int veid, char *dev_name_ve) static char * openvzGenerateContainerVethName(int veid) { - char temp[1024]; + char *temp = NULL; + char *name = NULL; /* try to get line "^NETIF=..." from config */ - if (openvzReadVPSConfigParam(veid, "NETIF", temp, sizeof(temp)) <= 0) { - snprintf(temp, sizeof(temp), "eth0"); + if (openvzReadVPSConfigParam(veid, "NETIF", &temp) <= 0) { + name = strdup("eth0"); } else { char *saveptr; - char *s; - int max = 0; + char *s; + int max = 0; /* get maximum interface number (actually, it is the last one) */ for (s=strtok_r(temp, ";", &saveptr); s; s=strtok_r(NULL, ";", &saveptr)) { @@ -650,9 +651,16 @@ openvzGenerateContainerVethName(int veid) } /* set new name */ - snprintf(temp, sizeof(temp), "eth%d", max+1); + virAsprintf(&name, "eth%d", max + 1); } - return strdup(temp); + + VIR_FREE(temp); + + if (name == NULL) { + virReportOOMError(); + } + + return name; } static int @@ -1125,7 +1133,7 @@ openvzDomainGetAutostart(virDomainPtr dom, int *autostart) { struct openvz_driver *driver = dom->conn->privateData; virDomainObjPtr vm; - char value[1024]; + char *value = NULL; int ret = -1; openvzDriverLock(driver); @@ -1138,7 +1146,7 @@ openvzDomainGetAutostart(virDomainPtr dom, int *autostart) goto cleanup; } - if (openvzReadVPSConfigParam(strtoI(vm->def->name), "ONBOOT", value, sizeof(value)) < 0) { + if (openvzReadVPSConfigParam(strtoI(vm->def->name), "ONBOOT", &value) < 0) { openvzError(VIR_ERR_INTERNAL_ERROR, "%s", _("Could not read container config")); goto cleanup; @@ -1150,6 +1158,8 @@ openvzDomainGetAutostart(virDomainPtr dom, int *autostart) ret = 0; cleanup: + VIR_FREE(value); + if (vm) virDomainObjUnlock(vm); return ret; @@ -1464,12 +1474,14 @@ out: return -1; } -static int openvzGetProcessInfo(unsigned long long *cpuTime, int vpsid) { - int fd; - char line[1024] ; +static int openvzGetProcessInfo(unsigned long long *cpuTime, int vpsid) +{ + FILE *fp; + char *line = NULL; + size_t line_size = 0; unsigned long long usertime, systime, nicetime; int readvps = vpsid + 1; /* ensure readvps is initially different */ - int ret; + ssize_t ret; /* read statistic from /proc/vz/vestat. sample: @@ -1479,12 +1491,12 @@ Version: 2.2 55 178 0 5340 59424597 542650441835148 other.. */ - if ((fd = open("/proc/vz/vestat", O_RDONLY)) == -1) + if ((fp = fopen("/proc/vz/vestat", "r")) == NULL) return -1; /*search line with VEID=vpsid*/ while (1) { - ret = openvz_readline(fd, line, sizeof(line)); + ret = getline(&line, &line_size, fp); if (ret <= 0) break; @@ -1499,7 +1511,8 @@ Version: 2.2 } } - VIR_FORCE_CLOSE(fd); + VIR_FREE(line); + VIR_FORCE_FCLOSE(fp); if (ret < 0) return -1; -- 1.7.0.4 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list