]> granicus.if.org Git - procps-ng/commitdiff
pgrep: Prevent integer overflow of list size.
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:21 +0000 (07:32 +1000)
Not exploitable (not under an attacker's control), but still a potential
non-security problem. Copied, fixed, and used the grow_size() macro from
pidof.c.

pgrep.c

diff --git a/pgrep.c b/pgrep.c
index ce8ccae9a18732298289136366995d425cb52d22..9887402d0bc5f8dec2a2dddf1885466ff424870d 100644 (file)
--- a/pgrep.c
+++ b/pgrep.c
 #include "proc/devname.h"
 #include "proc/sysinfo.h"
 
+#define grow_size(x) do { \
+       if ((x) < 0 || (size_t)(x) >= INT_MAX / 5 / sizeof(struct el)) \
+               xerrx(EXIT_FAILURE, _("integer overflow")); \
+       (x) = (x) * 5 / 4 + 4; \
+} while (0)
+
 static int i_am_pkill = 0;
 
 struct el {
@@ -158,7 +164,7 @@ static struct el *split_list (const char *restrict str, int (*convert)(const cha
 
        do {
                if (i == size) {
-                       size = size * 5 / 4 + 4;
+                       grow_size(size);
                        /* add 1 because slot zero is a count */
                        list = xrealloc (list, (1 + size) * sizeof *list);
                }
@@ -600,7 +606,7 @@ static struct el * select_procs (int *num)
                                matches = 0;
                        }
                        if (matches == size) {
-                               size = size * 5 / 4 + 4;
+                               grow_size(size);
                                list = xrealloc(list, size * sizeof *list);
                        }
                        if (list && (opt_long || opt_longlong || opt_echo)) {
@@ -624,10 +630,8 @@ static struct el * select_procs (int *num)
 
                                        // eventually grow output buffer
                                        if (matches == size) {
-                                               size = size * 5 / 4 + 4;
-                                               list = realloc(list, size * sizeof *list);
-                                               if (list == NULL)
-                                                       exit (EXIT_FATAL);
+                                               grow_size(size);
+                                               list = xrealloc(list, size * sizeof *list);
                                        }
                                        if (opt_long || opt_longlong) {
                                                list[matches].str = xstrdup (cmdoutput);