From aab2aaa360ef5774f14c0db96abcda63793d6033 Mon Sep 17 00:00:00 2001 From: Martin Kroeker Date: Thu, 7 Feb 2019 23:12:43 +0100 Subject: [PATCH 1/4] Fix potential memory leak in cpu enumeration with glibc An early return after a failed call to sched_getaffinity would leak the previously allocated cpu_set_t. Wrong calculation of the size argument in that call increased the likelyhood of that failure. Fixes #2003 --- driver/others/memory.c | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/driver/others/memory.c b/driver/others/memory.c index 2e185593e8..f35700d280 100644 --- a/driver/others/memory.c +++ b/driver/others/memory.c @@ -216,7 +216,7 @@ int i,n; #endif #if !__GLIBC_PREREQ(2, 7) - ret = sched_getaffinity(0,sizeof(cpu_set_t), cpusetp); + ret = sched_getaffinity(0,sizeof(cpusetp), cpusetp); if (ret!=0) return nums; n=0; #if !__GLIBC_PREREQ(2, 6) @@ -224,15 +224,18 @@ int i,n; if (CPU_ISSET(i,cpusetp)) n++; nums=n; #else - nums = CPU_COUNT(sizeof(cpu_set_t),cpusetp); + nums = CPU_COUNT(sizeof(cpusetp),cpusetp); #endif return nums; #else cpusetp = CPU_ALLOC(nums); if (cpusetp == NULL) return nums; size = CPU_ALLOC_SIZE(nums); - ret = sched_getaffinity(0,size,cpusetp); - if (ret!=0) return nums; + ret = sched_getaffinity(0,sizeof(cpusetp),cpusetp); + if (ret!=0) { + CPU_FREE(cpusetp); + return nums; + } ret = CPU_COUNT_S(size,cpusetp); if (ret > 0 && ret < nums) nums = ret; CPU_FREE(cpusetp); @@ -1728,7 +1731,7 @@ int i,n; #endif #if !__GLIBC_PREREQ(2, 7) - ret = sched_getaffinity(0,sizeof(cpu_set_t), cpusetp); + ret = sched_getaffinity(0,sizeof(cpusetp), cpusetp); if (ret!=0) return nums; n=0; #if !__GLIBC_PREREQ(2, 6) @@ -1736,15 +1739,18 @@ int i,n; if (CPU_ISSET(i,cpusetp)) n++; nums=n; #else - nums = CPU_COUNT(sizeof(cpu_set_t),cpusetp); + nums = CPU_COUNT(sizeof(cpusetp),cpusetp); #endif return nums; #else cpusetp = CPU_ALLOC(nums); if (cpusetp == NULL) return nums; size = CPU_ALLOC_SIZE(nums); - ret = sched_getaffinity(0,size,cpusetp); - if (ret!=0) return nums; + ret = sched_getaffinity(0,sizeof(cpusetp),cpusetp); + if (ret!=0) { + CPU_FREE(cpusetp); + return nums; + } ret = CPU_COUNT_S(size,cpusetp); if (ret > 0 && ret < nums) nums = ret; CPU_FREE(cpusetp); From cd6425add272815a78f90b5b467fc7fc66a60686 Mon Sep 17 00:00:00 2001 From: Martin Kroeker Date: Fri, 8 Feb 2019 09:17:23 +0100 Subject: [PATCH 2/4] Fix declarations of cpuset(p) --- driver/others/memory.c | 67 ++++++++++++++++++++++++++---------------- 1 file changed, 42 insertions(+), 25 deletions(-) diff --git a/driver/others/memory.c b/driver/others/memory.c index f35700d280..b55e5d5459 100644 --- a/driver/others/memory.c +++ b/driver/others/memory.c @@ -198,46 +198,54 @@ int get_num_procs(void); #else int get_num_procs(void) { static int nums = 0; -cpu_set_t *cpusetp; -size_t size; -int ret; -int i,n; + cpu_set_t cpuset,*cpusetp; + size_t size; + int ret; +#if !__GLIBC_PREREQ(2, 7) + int i; +#if !__GLIBC_PREREQ(2, 6) + int n; +#endif +#endif if (!nums) nums = sysconf(_SC_NPROCESSORS_CONF); #if !defined(OS_LINUX) - return nums; + return nums; #endif #if !defined(__GLIBC_PREREQ) - return nums; + return nums; #else #if !__GLIBC_PREREQ(2, 3) - return nums; + return nums; #endif #if !__GLIBC_PREREQ(2, 7) - ret = sched_getaffinity(0,sizeof(cpusetp), cpusetp); + ret = sched_getaffinity(0,sizeof(cpuset), &cpuset); if (ret!=0) return nums; n=0; #if !__GLIBC_PREREQ(2, 6) for (i=0;i 0 && ret < nums) nums = ret; + if (ret > 0 && ret < nums) nums = ret; CPU_FREE(cpusetp); return nums; #endif @@ -1712,41 +1720,50 @@ void goto_set_num_threads(int num_threads) {}; int get_num_procs(void); #else int get_num_procs(void) { + static int nums = 0; -cpu_set_t *cpusetp; -size_t size; -int ret; -int i,n; + cpu_set_t cpuset,*cpusetp; + size_t size; + int ret; +#if !__GLIBC_PREREQ(2, 7) + int i; +#if !__GLIBC_PREREQ(2, 6) + int n; +#endif +#endif if (!nums) nums = sysconf(_SC_NPROCESSORS_CONF); #if !defined(OS_LINUX) - return nums; + return nums; #endif #if !defined(__GLIBC_PREREQ) - return nums; + return nums; #else #if !__GLIBC_PREREQ(2, 3) - return nums; + return nums; #endif #if !__GLIBC_PREREQ(2, 7) - ret = sched_getaffinity(0,sizeof(cpusetp), cpusetp); + ret = sched_getaffinity(0,sizeof(cpuset), &cpuset); if (ret!=0) return nums; n=0; #if !__GLIBC_PREREQ(2, 6) for (i=0;i Date: Fri, 8 Feb 2019 11:54:49 +0100 Subject: [PATCH 3/4] Fixup ifdefs for non-glibc linux --- driver/others/memory.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/driver/others/memory.c b/driver/others/memory.c index b55e5d5459..263ce48728 100644 --- a/driver/others/memory.c +++ b/driver/others/memory.c @@ -201,11 +201,14 @@ int get_num_procs(void) { cpu_set_t cpuset,*cpusetp; size_t size; int ret; + +#if defined(__GLIBC_PREREQ) #if !__GLIBC_PREREQ(2, 7) int i; #if !__GLIBC_PREREQ(2, 6) int n; #endif +#endif #endif if (!nums) nums = sysconf(_SC_NPROCESSORS_CONF); @@ -1725,11 +1728,14 @@ int get_num_procs(void) { cpu_set_t cpuset,*cpusetp; size_t size; int ret; + +#if defined(__GLIBC_PREREQ) #if !__GLIBC_PREREQ(2, 7) int i; #if !__GLIBC_PREREQ(2, 6) int n; #endif +#endif #endif if (!nums) nums = sysconf(_SC_NPROCESSORS_CONF); From ad86d7ceb2cbafef8663fd1e5d1f83c4fefb346f Mon Sep 17 00:00:00 2001 From: Martin Kroeker Date: Sat, 9 Feb 2019 18:49:16 +0100 Subject: [PATCH 4/4] Disentangle pathways for cpu counts above and below 1024 --- driver/others/memory.c | 66 +++++++++++++++++++++++++++--------------- 1 file changed, 42 insertions(+), 24 deletions(-) diff --git a/driver/others/memory.c b/driver/others/memory.c index 263ce48728..09851f15c0 100644 --- a/driver/others/memory.c +++ b/driver/others/memory.c @@ -236,21 +236,30 @@ int get_num_procs(void) { #endif return nums; #else - cpusetp = CPU_ALLOC(nums); - if (cpusetp == NULL) { - return nums; - } - cpuset = *cpusetp; - size = CPU_ALLOC_SIZE(nums); - ret = sched_getaffinity(0,sizeof(cpuset),&cpuset); - if (ret!=0) { + if (nums >= CPU_SETSIZE) { + cpusetp = CPU_ALLOC(nums); + if (cpusetp == NULL) { + return nums; + } + size = CPU_ALLOC_SIZE(nums); + ret = sched_getaffinity(0,size,cpusetp); + if (ret!=0) { + CPU_FREE(cpusetp); + return nums; + } + ret = CPU_COUNT_S(size,cpusetp); + if (ret > 0 && ret < nums) nums = ret; CPU_FREE(cpusetp); return nums; + } else { + ret = sched_getaffinity(0,sizeof(cpuset),&cpuset); + if (ret!=0) { + return nums; + } + ret = CPU_COUNT(&cpuset); + if (ret > 0 && ret < nums) nums = ret; + return nums; } - ret = CPU_COUNT_S(size,cpusetp); - if (ret > 0 && ret < nums) nums = ret; - CPU_FREE(cpusetp); - return nums; #endif #endif } @@ -1763,21 +1772,30 @@ int get_num_procs(void) { #endif return nums; #else - cpusetp = CPU_ALLOC(nums); - if (cpusetp == NULL) { - return nums; - } - cpuset = *cpusetp; - size = CPU_ALLOC_SIZE(nums); - ret = sched_getaffinity(0,sizeof(cpuset),&cpuset); - if (ret!=0) { + if (nums >= CPU_SETSIZE) { + cpusetp = CPU_ALLOC(nums); + if (cpusetp == NULL) { + return nums; + } + size = CPU_ALLOC_SIZE(nums); + ret = sched_getaffinity(0,size,cpusetp); + if (ret!=0) { + CPU_FREE(cpusetp); + return nums; + } + ret = CPU_COUNT_S(size,cpusetp); + if (ret > 0 && ret < nums) nums = ret; CPU_FREE(cpusetp); return nums; + } else { + ret = sched_getaffinity(0,sizeof(cpuset),&cpuset); + if (ret!=0) { + return nums; + } + ret = CPU_COUNT(&cpuset); + if (ret > 0 && ret < nums) nums = ret; + return nums; } - ret = CPU_COUNT_S(size,cpusetp); - if (ret > 0 && ret < nums) nums = ret; - CPU_FREE(cpusetp); - return nums; #endif #endif }