Blob Blame History Raw
commit 11694bffe991a989468f017109697d17824fad28
Author: Nathan Scott <nathans@redhat.com>
Date:   Mon Mar 30 16:12:47 2020 +1100

    pcp-atop: ensure allocated task memory is always initialised
    
    We've received a report from a customer and intermittent failures
    in test qa/1080 from valgrind, along these lines:
    
    Invalid read of size 8
    at 0x4248A1: compcpu (showlinux.c:2031)
    by 0x4B38E74: msort_with_tmp.part.0 (in /usr/lib64/libc-2.30.so)
    by 0x4B38E01: msort_with_tmp.part.0 (in /usr/lib64/libc-2.30.so)
    by 0x4B38E01: msort_with_tmp.part.0 (in /usr/lib64/libc-2.30.so)
    by 0x4B38E01: msort_with_tmp.part.0 (in /usr/lib64/libc-2.30.so)
    by 0x4B38E01: msort_with_tmp.part.0 (in /usr/lib64/libc-2.30.so)
    by 0x4B38E01: msort_with_tmp.part.0 (in /usr/lib64/libc-2.30.so)
    by 0x4B38E01: msort_with_tmp.part.0 (in /usr/lib64/libc-2.30.so)
    by 0x4B39345: qsort_r (in /usr/lib64/libc-2.30.so)
    by 0x41CA8A: generic_samp (showgeneric.c:645)
    by 0x4043E7: engine (atop.c:686)
    by 0x403F07: main (atop.c:478)
    Address 0x188 is not stack'd, malloc'd or (recently) free'd
    
    I've found a couple of places where we might read uninitialized
    memory after a malloc - closed those holes, and now running the
    test in a loop 250 times, I've not observed the issue anymore.

diff --git a/src/pcp/atop/showgeneric.c b/src/pcp/atop/showgeneric.c
index f643132c3..50c52685f 100644
--- a/src/pcp/atop/showgeneric.c
+++ b/src/pcp/atop/showgeneric.c
@@ -336,7 +336,7 @@ generic_samp(double sampletime, double nsecs,
 			move(curline, 0);
 
 			limitedlines();
-			
+
 			curline = prisyst(sstat, curline, nsecs, avgval,
 					fixedhead,  &syssel, &autoorder,
 					maxcpulines, maxdsklines, maxmddlines,
@@ -448,7 +448,7 @@ generic_samp(double sampletime, double nsecs,
 			** one entry per user (list has worst-case size)
 			*/
 			tucumlist = calloc(sizeof(struct tstat),    nproc);
-			ucumlist  = malloc(sizeof(struct tstat *) * nproc);
+			ucumlist  = calloc(sizeof(struct tstat *),  nproc);
 
 			ptrverify(tucumlist,
 			        "Malloc failed for %d ucum procs\n", nproc);
@@ -491,7 +491,7 @@ generic_samp(double sampletime, double nsecs,
 			** one entry per program (list has worst-case size)
 			*/
 			tpcumlist = calloc(sizeof(struct tstat),    nproc);
-			pcumlist  = malloc(sizeof(struct tstat *) * nproc);
+			pcumlist  = calloc(sizeof(struct tstat *),  nproc);
 
 			ptrverify(tpcumlist,
 			        "Malloc failed for %d pcum procs\n", nproc);
@@ -534,7 +534,7 @@ generic_samp(double sampletime, double nsecs,
 			** one entry per user (list has worst-case size)
 			*/
 			tccumlist = calloc(sizeof(struct tstat),    nproc);
-			ccumlist  = malloc(sizeof(struct tstat *) * nproc);
+			ccumlist  = calloc(sizeof(struct tstat *),  nproc);
 
 			ptrverify(tccumlist,
 			        "Malloc failed for %d ccum procs\n", nproc);
@@ -590,7 +590,7 @@ generic_samp(double sampletime, double nsecs,
 			if (sellist)	// remove previous list if needed
 				free(sellist);
 
-			sellist = malloc(sizeof(struct tstat *) * ncurlist);
+			sellist = calloc(sizeof(struct tstat *), ncurlist);
 
 			ptrverify(sellist,
 			       "Malloc failed for %d select ptrs\n", ncurlist);
@@ -672,8 +672,8 @@ generic_samp(double sampletime, double nsecs,
 					if (tsklist)
 						free(tsklist);	// remove current
 
-					tsklist = malloc(sizeof(struct tstat *)
-								    * ntotal);
+					tsklist = calloc(sizeof(struct tstat *),
+								    ntotal);
 
 					ptrverify(tsklist,
 				             "Malloc failed for %d taskptrs\n",