Reuse the buffer for getline and track buffer allocation separately from the string length to prevent unlikely out-of-bounds memory access. This fixes the following leak that happened when zero bytes were read: ==404== 120 bytes in 1 blocks are definitely lost in loss record 1,344 of 1,671 ==404== at 0x4C2C71B: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so) ==404== by 0x906F862: getdelim (iogetdelim.c:68) ==404== by 0x52A48FB: virCgroupPartitionNeedsEscaping (vircgroup.c:1136) ==404== by 0x52A0FB4: virCgroupPartitionEscape (vircgroup.c:1171) ==404== by 0x52A0EA4: virCgroupNewDomainPartition (vircgroup.c:1450) --- v1: cgroup: Free line even if no characters were read https://www.redhat.com/archives/libvir-list/2013-July/msg01030.html src/util/vircgroup.c | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/util/vircgroup.c b/src/util/vircgroup.c index 5a98393..9dfe98d 100644 --- a/src/util/vircgroup.c +++ b/src/util/vircgroup.c @@ -1098,13 +1098,13 @@ cleanup: #if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R static int virCgroupPartitionNeedsEscaping(const char *path) { FILE *fp = NULL; int ret = 0; char *line = NULL; - size_t len; + size_t buflen; /* If it starts with 'cgroup.' or a '_' of any * of the controller names from /proc/cgroups, * then we must prefix a '_' */ if (STRPREFIX(path, "cgroup.")) @@ -1130,37 +1130,37 @@ static int virCgroupPartitionNeedsEscaping(const char *path) * cpuacct 3 48 1 * memory 4 4 1 * devices 5 4 1 * freezer 6 4 1 * net_cls 7 1 1 */ - while (getline(&line, &len, fp) > 0) { - if (STRPREFIX(line, "#subsys_name")) { - VIR_FREE(line); + while (getline(&line, &buflen, fp) > 0) { + char *tmp; + size_t len; + + if (STRPREFIX(line, "#subsys_name")) continue; - } - char *tmp = strchr(line, ' '); - if (tmp) - *tmp = '\0'; + + tmp = strchrnul(line, ' '); + *tmp = '\0'; len = tmp - line; if (STRPREFIX(path, line) && path[len] == '.') { ret = 1; - VIR_FREE(line); goto cleanup; } - VIR_FREE(line); } if (ferror(fp)) { ret = -EIO; goto cleanup; } cleanup: + VIR_FREE(line); VIR_FORCE_FCLOSE(fp); return ret; } static int virCgroupPartitionEscape(char **path) { -- 1.8.1.5 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list