top: Prevent integer overflows in procs_refresh().

This is very similar to our patch against integer overflows in
readproctab*().
This commit is contained in:
Qualys Security Advisory 1970-01-01 00:00:00 +00:00 committed by Craig Small
parent b6be15d3cb
commit 131e5e2fe6

View File

@ -22,6 +22,7 @@
#include <fcntl.h> #include <fcntl.h>
#include <float.h> #include <float.h>
#include <limits.h> #include <limits.h>
#include <stdint.h>
#include <pwd.h> #include <pwd.h>
#include <signal.h> #include <signal.h>
#include <stdarg.h> #include <stdarg.h>
@ -2717,6 +2718,15 @@ static inline void hstput (unsigned idx) {
#undef _HASH_ #undef _HASH_
#endif #endif
#define grow_by_size(nmemb, over, size) do { \
if ((nmemb) < 0 || (size_t)(nmemb) >= INT_MAX / 5) \
error_exit("integer overflow in procs_refresh"); \
(nmemb) = (nmemb) * 5 / 4 + (over); \
if ((nmemb) < 0 || (size_t)(nmemb) >= SSIZE_MAX / (size)) \
error_exit("integer overflow in procs_refresh"); \
} while (0)
/* /*
* Refresh procs *Helper* function to eliminate yet one more need * Refresh procs *Helper* function to eliminate yet one more need
* to loop through our darn proc_t table. He's responsible for: * to loop through our darn proc_t table. He's responsible for:
@ -2788,7 +2798,7 @@ static void procs_hlp (proc_t *this) {
} }
if (Frame_maxtask+1 >= HHist_siz) { if (Frame_maxtask+1 >= HHist_siz) {
HHist_siz = HHist_siz * 5 / 4 + 100; grow_by_size(HHist_siz, 100, sizeof(HST_t));
PHist_sav = alloc_r(PHist_sav, sizeof(HST_t) * HHist_siz); PHist_sav = alloc_r(PHist_sav, sizeof(HST_t) * HHist_siz);
PHist_new = alloc_r(PHist_new, sizeof(HST_t) * HHist_siz); PHist_new = alloc_r(PHist_new, sizeof(HST_t) * HHist_siz);
} }
@ -2850,7 +2860,7 @@ static void procs_refresh (void) {
for (;;) { for (;;) {
if (n_used == n_alloc) { if (n_used == n_alloc) {
n_alloc = 10 + ((n_alloc * 5) / 4); // grow by over 25% grow_by_size(n_alloc, 10, sizeof(proc_t*));
private_ppt = alloc_r(private_ppt, sizeof(proc_t*) * n_alloc); private_ppt = alloc_r(private_ppt, sizeof(proc_t*) * n_alloc);
// ensure NULL pointers for the additional memory just acquired // ensure NULL pointers for the additional memory just acquired
memset(private_ppt + n_used, 0, sizeof(proc_t*) * (n_alloc - n_used)); memset(private_ppt + n_used, 0, sizeof(proc_t*) * (n_alloc - n_used));
@ -2877,6 +2887,8 @@ static void procs_refresh (void) {
#undef n_used #undef n_used
} // end: procs_refresh } // end: procs_refresh
#undef grow_by_size
/* /*
* This serves as our interface to the memory & cpu count (sysinfo) * This serves as our interface to the memory & cpu count (sysinfo)