[libvirt] [PATCH v2] cgroup: reuse buffer for getline

Ján Tomko jtomko at redhat.com
Wed Jul 17 10:00:31 UTC 2013


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




More information about the libvir-list mailing list