]> granicus.if.org Git - procps-ng/commitdiff
top: Prevent integer overflows in procs_refresh().
authorQualys Security Advisory <qsa@qualys.com>
Thu, 1 Jan 1970 00:00:00 +0000 (00:00 +0000)
committerCraig Small <csmall@enc.com.au>
Fri, 18 May 2018 21:32:34 +0000 (07:32 +1000)
This is very similar to our patch against integer overflows in
readproctab*().

top/top.c

index de58d65565d0220430c915940de5765c939956f7..eda3d265d5ef404f240d67be72318b8881f4b014 100644 (file)
--- a/top/top.c
+++ b/top/top.c
@@ -22,6 +22,7 @@
 #include <fcntl.h>
 #include <float.h>
 #include <limits.h>
+#include <stdint.h>
 #include <pwd.h>
 #include <signal.h>
 #include <stdarg.h>
@@ -2717,6 +2718,15 @@ static inline void hstput (unsigned idx) {
 #undef _HASH_
 #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
          * 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) {
-      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_new = alloc_r(PHist_new, sizeof(HST_t) * HHist_siz);
    }
@@ -2850,7 +2860,7 @@ static void procs_refresh (void) {
 
    for (;;) {
       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);
          // ensure NULL pointers for the additional memory just acquired
          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
 } // end: procs_refresh
 
+#undef grow_by_size
+
 
         /*
          * This serves as our interface to the memory & cpu count (sysinfo)