Skip to content

Commit 03a2bf2

Browse files
authored
Fix potential memory leak in cpu enumeration on Linux (#2008)
* 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
1 parent 69edc5b commit 03a2bf2

File tree

1 file changed

+85
-38
lines changed

1 file changed

+85
-38
lines changed

driver/others/memory.c

+85-38
Original file line numberDiff line numberDiff line change
@@ -198,45 +198,68 @@ int get_num_procs(void);
198198
#else
199199
int get_num_procs(void) {
200200
static int nums = 0;
201-
cpu_set_t *cpusetp;
202-
size_t size;
203-
int ret;
204-
int i,n;
201+
cpu_set_t cpuset,*cpusetp;
202+
size_t size;
203+
int ret;
204+
205+
#if defined(__GLIBC_PREREQ)
206+
#if !__GLIBC_PREREQ(2, 7)
207+
int i;
208+
#if !__GLIBC_PREREQ(2, 6)
209+
int n;
210+
#endif
211+
#endif
212+
#endif
205213

206214
if (!nums) nums = sysconf(_SC_NPROCESSORS_CONF);
207215
#if !defined(OS_LINUX)
208-
return nums;
216+
return nums;
209217
#endif
210218

211219
#if !defined(__GLIBC_PREREQ)
212-
return nums;
220+
return nums;
213221
#else
214222
#if !__GLIBC_PREREQ(2, 3)
215-
return nums;
223+
return nums;
216224
#endif
217225

218226
#if !__GLIBC_PREREQ(2, 7)
219-
ret = sched_getaffinity(0,sizeof(cpu_set_t), cpusetp);
227+
ret = sched_getaffinity(0,sizeof(cpuset), &cpuset);
220228
if (ret!=0) return nums;
221229
n=0;
222230
#if !__GLIBC_PREREQ(2, 6)
223231
for (i=0;i<nums;i++)
224-
if (CPU_ISSET(i,cpusetp)) n++;
232+
if (CPU_ISSET(i,cpuset)) n++;
225233
nums=n;
226234
#else
227-
nums = CPU_COUNT(sizeof(cpu_set_t),cpusetp);
235+
nums = CPU_COUNT(sizeof(cpuset),&cpuset);
228236
#endif
229237
return nums;
230238
#else
231-
cpusetp = CPU_ALLOC(nums);
232-
if (cpusetp == NULL) return nums;
233-
size = CPU_ALLOC_SIZE(nums);
234-
ret = sched_getaffinity(0,size,cpusetp);
235-
if (ret!=0) return nums;
236-
ret = CPU_COUNT_S(size,cpusetp);
237-
if (ret > 0 && ret < nums) nums = ret;
238-
CPU_FREE(cpusetp);
239-
return nums;
239+
if (nums >= CPU_SETSIZE) {
240+
cpusetp = CPU_ALLOC(nums);
241+
if (cpusetp == NULL) {
242+
return nums;
243+
}
244+
size = CPU_ALLOC_SIZE(nums);
245+
ret = sched_getaffinity(0,size,cpusetp);
246+
if (ret!=0) {
247+
CPU_FREE(cpusetp);
248+
return nums;
249+
}
250+
ret = CPU_COUNT_S(size,cpusetp);
251+
if (ret > 0 && ret < nums) nums = ret;
252+
CPU_FREE(cpusetp);
253+
return nums;
254+
} else {
255+
ret = sched_getaffinity(0,sizeof(cpuset),&cpuset);
256+
if (ret!=0) {
257+
return nums;
258+
}
259+
ret = CPU_COUNT(&cpuset);
260+
if (ret > 0 && ret < nums) nums = ret;
261+
return nums;
262+
}
240263
#endif
241264
#endif
242265
}
@@ -1709,46 +1732,70 @@ void goto_set_num_threads(int num_threads) {};
17091732
int get_num_procs(void);
17101733
#else
17111734
int get_num_procs(void) {
1735+
17121736
static int nums = 0;
1713-
cpu_set_t *cpusetp;
1714-
size_t size;
1715-
int ret;
1716-
int i,n;
1737+
cpu_set_t cpuset,*cpusetp;
1738+
size_t size;
1739+
int ret;
1740+
1741+
#if defined(__GLIBC_PREREQ)
1742+
#if !__GLIBC_PREREQ(2, 7)
1743+
int i;
1744+
#if !__GLIBC_PREREQ(2, 6)
1745+
int n;
1746+
#endif
1747+
#endif
1748+
#endif
17171749

17181750
if (!nums) nums = sysconf(_SC_NPROCESSORS_CONF);
17191751
#if !defined(OS_LINUX)
1720-
return nums;
1752+
return nums;
17211753
#endif
17221754

17231755
#if !defined(__GLIBC_PREREQ)
1724-
return nums;
1756+
return nums;
17251757
#else
17261758
#if !__GLIBC_PREREQ(2, 3)
1727-
return nums;
1759+
return nums;
17281760
#endif
17291761

17301762
#if !__GLIBC_PREREQ(2, 7)
1731-
ret = sched_getaffinity(0,sizeof(cpu_set_t), cpusetp);
1763+
ret = sched_getaffinity(0,sizeof(cpuset), &cpuset);
17321764
if (ret!=0) return nums;
17331765
n=0;
17341766
#if !__GLIBC_PREREQ(2, 6)
17351767
for (i=0;i<nums;i++)
1736-
if (CPU_ISSET(i,cpusetp)) n++;
1768+
if (CPU_ISSET(i,cpuset)) n++;
17371769
nums=n;
17381770
#else
1739-
nums = CPU_COUNT(sizeof(cpu_set_t),cpusetp);
1771+
nums = CPU_COUNT(sizeof(cpuset),&cpuset);
17401772
#endif
17411773
return nums;
17421774
#else
1743-
cpusetp = CPU_ALLOC(nums);
1744-
if (cpusetp == NULL) return nums;
1745-
size = CPU_ALLOC_SIZE(nums);
1746-
ret = sched_getaffinity(0,size,cpusetp);
1747-
if (ret!=0) return nums;
1748-
ret = CPU_COUNT_S(size,cpusetp);
1749-
if (ret > 0 && ret < nums) nums = ret;
1750-
CPU_FREE(cpusetp);
1751-
return nums;
1775+
if (nums >= CPU_SETSIZE) {
1776+
cpusetp = CPU_ALLOC(nums);
1777+
if (cpusetp == NULL) {
1778+
return nums;
1779+
}
1780+
size = CPU_ALLOC_SIZE(nums);
1781+
ret = sched_getaffinity(0,size,cpusetp);
1782+
if (ret!=0) {
1783+
CPU_FREE(cpusetp);
1784+
return nums;
1785+
}
1786+
ret = CPU_COUNT_S(size,cpusetp);
1787+
if (ret > 0 && ret < nums) nums = ret;
1788+
CPU_FREE(cpusetp);
1789+
return nums;
1790+
} else {
1791+
ret = sched_getaffinity(0,sizeof(cpuset),&cpuset);
1792+
if (ret!=0) {
1793+
return nums;
1794+
}
1795+
ret = CPU_COUNT(&cpuset);
1796+
if (ret > 0 && ret < nums) nums = ret;
1797+
return nums;
1798+
}
17521799
#endif
17531800
#endif
17541801
}

0 commit comments

Comments
 (0)