Blame SOURCES/bz1064254.patch

95ec45
commit 5ebdf2fe3f1aca661ed1a13a6aa45e3c27d228c2
95ec45
Author: Nathan Scott <nathans@redhat.com>
95ec45
Date:   Thu Feb 13 14:12:49 2014 +1100
95ec45
95ec45
    Fix valgrind errors in pmdalinux /proc/stat refresh
95ec45
    
95ec45
    This one has bugged me for a long time, and I finally needed to spend
95ec45
    some time hunting an obscure memory corruption in pmdalinux - so got
95ec45
    to revisit this properly.
95ec45
    
95ec45
    There were a few small problems in refresh_proc_stat causing valgrind
95ec45
    to report "invalid read of zero size".  Most problematic was the code
95ec45
    reading the stat buffer initially, which slightly confuses the offset
95ec45
    and size combo in passing a buffer pointer to read(2).  The realloc
95ec45
    call here also happened to allocate 8x the (small) memory it wanted,
95ec45
    accidently multiplying the size by sizeof(char).
95ec45
    
95ec45
    The nbufindex calculation also ended up with one more line than was
95ec45
    in the buffer, which was OK because it always created an empty line
95ec45
    at the end of it (which doesn't actually exist in /proc/stat).
95ec45
    
95ec45
    Finally, added some small improvements to the handling of ENOMEM for
95ec45
    these global stat buffers, and removed a double-memset on the initial
95ec45
    call (which callocs a zeroed buffer).
95ec45
95ec45
diff --git a/src/pmdas/linux/proc_stat.c b/src/pmdas/linux/proc_stat.c
95ec45
index f4e001c..234b713 100644
95ec45
--- a/src/pmdas/linux/proc_stat.c
95ec45
+++ b/src/pmdas/linux/proc_stat.c
95ec45
@@ -1,7 +1,7 @@
95ec45
 /*
95ec45
  * Linux /proc/stat metrics cluster
95ec45
  *
95ec45
- * Copyright (c) 2012 Red Hat.
95ec45
+ * Copyright (c) 2012-2014 Red Hat.
95ec45
  * Copyright (c) 2008-2009 Aconex.  All Rights Reserved.
95ec45
  * Copyright (c) 2000,2004-2008 Silicon Graphics, Inc.  All Rights Reserved.
95ec45
  * 
95ec45
@@ -39,22 +39,28 @@ refresh_proc_stat(proc_cpuinfo_t *proc_cpuinfo, proc_stat_t *proc_stat)
95ec45
     static char **bufindex;
95ec45
     static int nbufindex;
95ec45
     static int maxbufindex;
95ec45
+    int size;
95ec45
     int n;
95ec45
     int i;
95ec45
     int j;
95ec45
 
95ec45
-    if (fd >= 0)
95ec45
-    	lseek(fd, 0, SEEK_SET);
95ec45
-    else
95ec45
+    if (fd >= 0) {
95ec45
+	if (lseek(fd, 0, SEEK_SET) < 0)
95ec45
+	    return -oserror();
95ec45
+    } else {
95ec45
 	if ((fd = open("/proc/stat", O_RDONLY)) < 0)
95ec45
 	    return -oserror();
95ec45
+    }
95ec45
 
95ec45
     for (n=0;;) {
95ec45
-	if (n >= maxstatbuf) {
95ec45
-	    maxstatbuf += 512;
95ec45
-	    statbuf = (char *)realloc(statbuf, maxstatbuf * sizeof(char));
95ec45
+	while (n >= maxstatbuf) {
95ec45
+	    size = maxstatbuf + 512;
95ec45
+	    if ((statbuf = (char *)realloc(statbuf, size)) == NULL)
95ec45
+		return -ENOMEM;
95ec45
+	    maxstatbuf = size;
95ec45
 	}
95ec45
-	if ((i = read(fd, statbuf+n, 512)) > 0)
95ec45
+	size = (statbuf + maxstatbuf) - (statbuf + n);
95ec45
+	if ((i = read(fd, statbuf + n, size)) > 0)
95ec45
 	    n += i;
95ec45
 	else
95ec45
 	    break;
95ec45
@@ -62,20 +68,24 @@ refresh_proc_stat(proc_cpuinfo_t *proc_cpuinfo, proc_stat_t *proc_stat)
95ec45
     statbuf[n] = '\0';
95ec45
 
95ec45
     if (bufindex == NULL) {
95ec45
+	size = 4 * sizeof(char *);
95ec45
+	if ((bufindex = (char **)malloc(size)) == NULL)
95ec45
+	    return -ENOMEM;
95ec45
 	maxbufindex = 4;
95ec45
-	bufindex = (char **)malloc(maxbufindex * sizeof(char *));
95ec45
     }
95ec45
 
95ec45
     nbufindex = 0;
95ec45
-    bufindex[nbufindex++] = statbuf;
95ec45
+    bufindex[nbufindex] = statbuf;
95ec45
     for (i=0; i < n; i++) {
95ec45
-	if (statbuf[i] == '\n') {
95ec45
+	if (statbuf[i] == '\n' || statbuf[i] == '\0') {
95ec45
 	    statbuf[i] = '\0';
95ec45
-	    if (nbufindex >= maxbufindex) {
95ec45
+	    if (nbufindex + 1 >= maxbufindex) {
95ec45
+		size = (maxbufindex + 4) * sizeof(char *);
95ec45
+		if ((bufindex = (char **)realloc(bufindex, size)) == NULL)
95ec45
+		    return -ENOMEM;
95ec45
 	    	maxbufindex += 4;
95ec45
-		bufindex = (char **)realloc(bufindex, maxbufindex * sizeof(char *));
95ec45
 	    }
95ec45
-	    bufindex[nbufindex++] = statbuf + i + 1;
95ec45
+	    bufindex[++nbufindex] = statbuf + i + 1;
95ec45
 	}
95ec45
     }
95ec45
 
95ec45
@@ -130,19 +140,19 @@ refresh_proc_stat(proc_cpuinfo_t *proc_cpuinfo, proc_stat_t *proc_stat)
95ec45
 	proc_stat->n_steal = calloc(1, n);
95ec45
 	proc_stat->n_guest = calloc(1, n);
95ec45
     }
95ec45
-
95ec45
-    /* reset per-node stats */
95ec45
-    n = proc_cpuinfo->node_indom->it_numinst * sizeof(unsigned long long);
95ec45
-    memset(proc_stat->n_user, 0, n);
95ec45
-    memset(proc_stat->n_nice, 0, n);
95ec45
-    memset(proc_stat->n_sys, 0, n);
95ec45
-    memset(proc_stat->n_idle, 0, n);
95ec45
-    memset(proc_stat->n_wait, 0, n);
95ec45
-    memset(proc_stat->n_irq, 0, n);
95ec45
-    memset(proc_stat->n_sirq, 0, n);
95ec45
-    memset(proc_stat->n_steal, 0, n);
95ec45
-    memset(proc_stat->n_guest, 0, n);
95ec45
-
95ec45
+    else {
95ec45
+	/* reset per-node stats */
95ec45
+	n = proc_cpuinfo->node_indom->it_numinst * sizeof(unsigned long long);
95ec45
+	memset(proc_stat->n_user, 0, n);
95ec45
+	memset(proc_stat->n_nice, 0, n);
95ec45
+	memset(proc_stat->n_sys, 0, n);
95ec45
+	memset(proc_stat->n_idle, 0, n);
95ec45
+	memset(proc_stat->n_wait, 0, n);
95ec45
+	memset(proc_stat->n_irq, 0, n);
95ec45
+	memset(proc_stat->n_sirq, 0, n);
95ec45
+	memset(proc_stat->n_steal, 0, n);
95ec45
+	memset(proc_stat->n_guest, 0, n);
95ec45
+    }
95ec45
     /*
95ec45
      * cpu  95379 4 20053 6502503
95ec45
      * 2.6 kernels have 3 additional fields
95ec45
95ec45
commit f5eaeea7900390ae007f5ed3375cadc6ca86497e
95ec45
Author: Nathan Scott <nathans@redhat.com>
95ec45
Date:   Thu Feb 13 14:20:52 2014 +1100
95ec45
95ec45
    Fix s390x platform issues in /proc/cpuinfo parser
95ec45
    
95ec45
    The format of /proc/cpuinfo on s390x is nothing like any other
95ec45
    platform.  We cannot attempt to push it through the same code
95ec45
    path, it simply has nothing in common.  If we try (as we used to)
95ec45
    things fall apart when we use the (negative) cpu number local
95ec45
    variable to index into the cpuinfo array.
95ec45
    
95ec45
    Resolved by adding in some defensive code to short-circuit the
95ec45
    decoding logic when an unexpected file format is seen.
95ec45
95ec45
diff --git a/src/pmdas/linux/proc_cpuinfo.c b/src/pmdas/linux/proc_cpuinfo.c
95ec45
index 6380bc2..d0aa52a 100644
95ec45
--- a/src/pmdas/linux/proc_cpuinfo.c
95ec45
+++ b/src/pmdas/linux/proc_cpuinfo.c
95ec45
@@ -1,7 +1,7 @@
95ec45
 /*
95ec45
  * Linux /proc/cpuinfo metrics cluster
95ec45
  *
95ec45
- * Copyright (c) 2013 Red Hat.
95ec45
+ * Copyright (c) 2013-2014 Red Hat.
95ec45
  * Copyright (c) 2000-2005 Silicon Graphics, Inc.  All Rights Reserved.
95ec45
  * Portions Copyright (c) 2001 Gilly Ran (gilly@exanet.com) - for the
95ec45
  * portions supporting the Alpha platform.  All rights reserved.
95ec45
@@ -185,6 +185,9 @@ refresh_proc_cpuinfo(proc_cpuinfo_t *proc_cpuinfo)
95ec45
 	}
95ec45
 #endif
95ec45
 
95ec45
+	if (cpunum < 0 || cpunum >= proc_cpuinfo->cpuindom->it_numinst)
95ec45
+	    continue;
95ec45
+
95ec45
 	info = &proc_cpuinfo->cpuinfo[cpunum];
95ec45
 
95ec45
 	/* note: order is important due to strNcmp comparisons */