Hello. I've prepared update for procps. Patches are backported from procps_3.3.9-9+deb8u1 (jessie). Debdiff is attached. I was able to install it on a clean machine and ran some procps commands. Please review and upload.
--abhijith
diff -Nru procps-3.3.3/debian/changelog procps-3.3.3/debian/changelog --- procps-3.3.3/debian/changelog 2013-03-28 10:58:19.000000000 +0000 +++ procps-3.3.3/debian/changelog 2018-05-30 16:55:10.000000000 +0000 @@ -1,3 +1,11 @@ +procps (1:3.3.3-3+deb7u1) wheezy-security; urgency=high + + * Non-maintainer upload by the Debian LTS team. + * Fix various vulnerabilities CVE-2018-1122, CVE-2018-1123, CVE-2018-1124, + CVE-2018-1125, CVE-2018-1126 (Closes: #899170) + + -- Abhijith PA <abhij...@disroot.org> Wed, 23 May 2018 13:15:16 +0530 + procps (1:3.3.3-3) testing-proposed-updates; urgency=medium * 3.3.3-3 Fix ps crash with large process groups Closes: #702965 diff -Nru procps-3.3.3/debian/patches/CVE-2018-1122.patch procps-3.3.3/debian/patches/CVE-2018-1122.patch --- procps-3.3.3/debian/patches/CVE-2018-1122.patch 1970-01-01 00:00:00.000000000 +0000 +++ procps-3.3.3/debian/patches/CVE-2018-1122.patch 2018-05-30 17:05:28.000000000 +0000 @@ -0,0 +1,53 @@ +Description: CVE-2018-1122 + procps-ng is vulnerable to a local privilege escalation in top. If a user + runs top with HOME unset in an attacker-controlled directory, the attacker + could achieve privilege escalation by exploiting one of several + vulnerabilities in the config_file() function. + +Author: Abhijith PA <abhij...@disroot.org> +Origin: backported from procps-2:3.3.9-9+deb8u1 jessie. +Bug-Debian: https://bugs.debian.org/899170 +Last-Update: 2018-05-23 + +--- procps-3.3.3.orig/top/top.c ++++ procps-3.3.3/top/top.c +@@ -2248,6 +2248,19 @@ static int config_cvt (WIN_t *q) { + return 0; + } // end: config_cvt + ++static int snprintf_Rc_name (const char *const format, ...) __attribute__((format(printf,1,2))); ++static int snprintf_Rc_name (const char *const format, ...) { ++ int len; ++ va_list ap; ++ va_start(ap, format); ++ len = vsnprintf(Rc_name, sizeof(Rc_name), format, ap); ++ va_end(ap); ++ if (len <= 0 || (size_t)len >= sizeof(Rc_name)) { ++ Rc_name[0] = '\0'; ++ return 0; ++ } ++ return len; ++} + + /* + * Build the local RC file name then try to read both of 'em. +@@ -2270,8 +2283,18 @@ static void configs_read (void) { + FILE *fp; + int i, x; + ++ Rc_name[0] = '\0'; // "fopen() shall fail if pathname is an empty string." + p = getenv("HOME"); +- snprintf(Rc_name, sizeof(Rc_name), "%s/.%src", (p && *p) ? p : ".", Myname); ++ ++ if (!p || p[0] != '/') { ++ const struct passwd *const pwd = getpwuid(getuid()); ++ if (!pwd || !(p = pwd->pw_dir) || p[0] != '/') { ++ p = NULL; ++ } ++ } ++ if (p) { ++ snprintf_Rc_name("%s/.%src", p, Myname); ++ } + + fp = fopen(SYS_RCFILESPEC, "r"); + if (fp) { diff -Nru procps-3.3.3/debian/patches/CVE-2018-1123.patch procps-3.3.3/debian/patches/CVE-2018-1123.patch --- procps-3.3.3/debian/patches/CVE-2018-1123.patch 1970-01-01 00:00:00.000000000 +0000 +++ procps-3.3.3/debian/patches/CVE-2018-1123.patch 2018-05-30 16:49:19.000000000 +0000 @@ -0,0 +1,75 @@ +Description: CVE-2018-1123 + procps-ng is vulnerable to a denial of service in ps via mmap buffer overflow. + Inbuilt protection in ps maps a guard page at the end of the overflowed buffer, + ensuring that the impact of this flaw is limited to a crash (temporary denial + of service). + + +Author: Abhijith PA <abhij...@disroot.org> +Origin: backported from procps-2:3.3.9-9+deb8u1 jessie. +Bug-Debian: https://bugs.debian.org/899170 +Last-Update: 2018-05-30 + +--- procps-3.3.3.orig/ps/output.c ++++ procps-3.3.3/ps/output.c +@@ -366,6 +366,9 @@ Modifications to the arguments are not s + + // FIXME: some of these may hit the guard page in forest mode + ++#define OUTBUF_SIZE_AT(endp) \ ++ (((endp) >= outbuf && (endp) < outbuf + OUTBUF_SIZE) ? (outbuf + OUTBUF_SIZE) - (endp) : 0) ++ + /* + * "args", "cmd", "command" are all the same: long unless c + * "comm", "ucmd", "ucomm" are all the same: short unless -f +@@ -379,13 +382,13 @@ static int pr_args(char *restrict const + rightward -= fh; + + if(pp->cmdline && !bsd_c_option) +- endp += escaped_copy(endp, *pp->cmdline, OUTBUF_SIZE, &rightward); ++ endp += escaped_copy(endp, *pp->cmdline, OUTBUF_SIZE_AT(endp), &rightward); + else +- endp += escape_command(endp, pp, OUTBUF_SIZE, &rightward, ESC_DEFUNCT); ++ endp += escape_command(endp, pp, OUTBUF_SIZE_AT(endp), &rightward, ESC_DEFUNCT); + +- if(bsd_e_option && rightward>1) { ++ if(bsd_e_option && rightward>1 && OUTBUF_SIZE_AT(endp)>1) { + if(pp->environ && *pp->environ) +- endp += escape_strlist(endp, pp->environ, OUTBUF_SIZE, &rightward); ++ endp += escape_strlist(endp, pp->environ, OUTBUF_SIZE_AT(endp), &rightward); + } + return max_rightward-rightward; + } +@@ -403,13 +406,13 @@ static int pr_comm(char *restrict const + rightward -= fh; + + if(pp->cmdline && unix_f_option) +- endp += escaped_copy(endp, *pp->cmdline, OUTBUF_SIZE, &rightward); ++ endp += escaped_copy(endp, *pp->cmdline, OUTBUF_SIZE_AT(endp), &rightward); + else +- endp += escape_command(endp, pp, OUTBUF_SIZE, &rightward, ESC_DEFUNCT); ++ endp += escape_command(endp, pp, OUTBUF_SIZE_AT(endp), &rightward, ESC_DEFUNCT); + +- if(bsd_e_option && rightward>1) { ++ if(bsd_e_option && rightward>1 && OUTBUF_SIZE_AT(endp)>1) { + if(pp->environ && *pp->environ) +- endp += escape_strlist(endp, pp->environ, OUTBUF_SIZE, &rightward); ++ endp += escape_strlist(endp, pp->environ, OUTBUF_SIZE_AT(endp), &rightward); + } + return max_rightward-rightward; + } +@@ -437,11 +440,13 @@ static int pr_fname(char *restrict const + if (rightward>8) /* 8=default, but forest maybe feeds more */ + rightward = 8; + +- endp += escape_str(endp, pp->cmd, OUTBUF_SIZE, &rightward); ++ endp += escape_str(endp, pp->cmd, OUTBUF_SIZE_AT(endp), &rightward); + //return endp - outbuf; + return max_rightward-rightward; + } + ++#undef OUTBUF_SIZE_AT ++ + /* elapsed wall clock time, [[dd-]hh:]mm:ss format (not same as "time") */ + static int pr_etime(char *restrict const outbuf, const proc_t *restrict const pp){ + unsigned long t; diff -Nru procps-3.3.3/debian/patches/CVE-2018-1124.patch procps-3.3.3/debian/patches/CVE-2018-1124.patch --- procps-3.3.3/debian/patches/CVE-2018-1124.patch 1970-01-01 00:00:00.000000000 +0000 +++ procps-3.3.3/debian/patches/CVE-2018-1124.patch 2018-05-30 16:49:20.000000000 +0000 @@ -0,0 +1,117 @@ +Description: CVE-2018-1124 + procps-ng is vulnerable to multiple integer overflows leading to a heap + corruption in file2strvec function. This allows a privilege escalation for a + local attacker who can create entries in procfs by starting processes, which + could result in crashes or arbitrary code execution in proc utilities run by + other users. + +Author: Abhijith PA <abhij...@disroot.org> +Origin: backported from procps-2:3.3.9-9+deb8u1 jessie. +Bug-Debian: https://bugs.debian.org/899170 +Last-Update: 2018-05-30 + +Index: procps-3.3.3/proc/readproc.c +=================================================================== +--- procps-3.3.3.orig/proc/readproc.c ++++ procps-3.3.3/proc/readproc.c +@@ -37,6 +37,7 @@ + #include <sys/dir.h> + #include <sys/types.h> + #include <sys/stat.h> ++#include <limits.h> + + // sometimes it's easier to do this manually, w/o gcc helping + #ifdef PROF +@@ -540,11 +541,12 @@ static int file2str(const char *director + + static char** file2strvec(const char* directory, const char* what) { + char buf[2048]; /* read buf bytes at a time */ +- char *p, *rbuf = 0, *endbuf, **q, **ret; ++ char *p, *rbuf = 0, *endbuf, **q, **ret, *strp; + int fd, tot = 0, n, c, end_of_file = 0; + int align; + +- sprintf(buf, "%s/%s", directory, what); ++ const int len = snprintf(buf, sizeof buf, "%s/%s", directory, what); ++ if(len <= 0 || (size_t)len >= sizeof buf) return NULL; + fd = open(buf, O_RDONLY, 0); + if(fd==-1) return NULL; + +@@ -552,18 +554,23 @@ static char** file2strvec(const char* di + while ((n = read(fd, buf, sizeof buf - 1)) >= 0) { + if (n < (int)(sizeof buf - 1)) + end_of_file = 1; +- if (n == 0 && rbuf == 0) { +- close(fd); +- return NULL; /* process died between our open and read */ ++ if (n <= 0 && tot <= 0) { /* nothing read now, nothing read before */ ++ break; /* process died between our open and read */ + } +- if (n < 0) { +- if (rbuf) +- free(rbuf); +- close(fd); +- return NULL; /* read error */ ++ /* ARG_LEN is our guesstimated median length of a command-line argument ++ or environment variable (the minimum is 1, the maximum is 131072) */ ++ #define ARG_LEN 64 ++ if (tot >= INT_MAX / (ARG_LEN + (int)sizeof(char*)) * ARG_LEN - n) { ++ end_of_file = 1; /* integer overflow: null-terminate and break */ ++ n = 0; /* but tot > 0 */ + } +- if (end_of_file && (n == 0 || buf[n-1]))/* last read char not null */ ++ #undef ARG_LEN ++ if (end_of_file && ++ ((n > 0 && buf[n-1] != '\0') || /* last read char not null */ ++ (n <= 0 && rbuf[tot-1] != '\0'))) /* last read char not null */ + buf[n++] = '\0'; /* so append null-terminator */ ++ ++ if (n <= 0) break; /* unneeded (end_of_file = 1) but avoid realloc */ + rbuf = xrealloc(rbuf, tot + n); /* allocate more memory */ + memcpy(rbuf + tot, buf, n); /* copy buffer into it */ + tot += n; /* increment total byte ctr */ +@@ -571,29 +578,34 @@ static char** file2strvec(const char* di + break; + } + close(fd); +- if (n <= 0 && !end_of_file) { ++ if (n < 0 || tot <= 0) { /* error, or nothing read */ + if (rbuf) free(rbuf); + return NULL; /* read error */ + } ++ rbuf[tot-1] = '\0'; /* belt and suspenders (the while loop did it, too) */ + endbuf = rbuf + tot; /* count space for pointers */ + align = (sizeof(char*)-1) - ((tot + sizeof(char*)-1) & (sizeof(char*)-1)); +- for (c = 0, p = rbuf; p < endbuf; p++) { +- if (!*p || *p == '\n') ++ c = sizeof(char*); /* one extra for NULL term */ ++ for (p = rbuf; p < endbuf; p++) { ++ if (!*p || *p == '\n') { ++ if (c >= INT_MAX - (tot + (int)sizeof(char*) + align)) break; + c += sizeof(char*); ++ } + if (*p == '\n') + *p = 0; + } +- c += sizeof(char*); /* one extra for NULL term */ + + rbuf = xrealloc(rbuf, tot + c + align); /* make room for ptrs AT END */ + endbuf = rbuf + tot; /* addr just past data buf */ + q = ret = (char**) (endbuf+align); /* ==> free(*ret) to dealloc */ +- *q++ = p = rbuf; /* point ptrs to the strings */ +- endbuf--; /* do not traverse final NUL */ +- while (++p < endbuf) +- if (!*p) /* NUL char implies that */ +- *q++ = p+1; /* next string -> next char */ +- ++ for (strp = p = rbuf; p < endbuf; p++) { ++ if (!*p) { /* NUL char implies that */ ++ if (c < 2 * (int)sizeof(char*)) break; ++ c -= sizeof(char*); ++ *q++ = strp; /* point ptrs to the strings */ ++ strp = p+1; /* next string -> next char */ ++ } ++ } + *q = 0; /* null ptr list terminator */ + return ret; + } diff -Nru procps-3.3.3/debian/patches/CVE-2018-1125.patch procps-3.3.3/debian/patches/CVE-2018-1125.patch --- procps-3.3.3/debian/patches/CVE-2018-1125.patch 1970-01-01 00:00:00.000000000 +0000 +++ procps-3.3.3/debian/patches/CVE-2018-1125.patch 2018-05-30 16:49:18.000000000 +0000 @@ -0,0 +1,47 @@ +Description: CVE-2018-1125 + procps-ng before version 3.3.15 is vulnerable to a stack buffer overflow in + pgrep. This vulnerability is mitigated by FORTIFY, as it involves strncat() to + a stack-allocated string. + +Author: Abhijith PA <abhij...@disroot.org> +Origin: backported from procps-2:3.3.9-9+deb8u1 jessie. +Bug-Debian: https://bugs.debian.org/899170 +Last-Update: 2018-05-30 + +--- procps-3.3.3.orig/pgrep.c ++++ procps-3.3.3/pgrep.c +@@ -498,19 +498,24 @@ static struct el * select_procs (int *nu + if (opt_long || (match && opt_pattern)) { + if (opt_full && task.cmdline) { + int i = 0; +- int bytes = sizeof (cmd) - 1; ++ int bytes = sizeof (cmd); ++ char *str = cmd; + + /* make sure it is always NUL-terminated */ +- cmd[bytes] = 0; +- /* make room for SPC in loop below */ +- --bytes; ++ *str = '\0'; + +- strncpy (cmd, task.cmdline[i], bytes); +- bytes -= strlen (task.cmdline[i++]); +- while (task.cmdline[i] && bytes > 0) { +- strncat (cmd, " ", bytes); +- strncat (cmd, task.cmdline[i], bytes); +- bytes -= strlen (task.cmdline[i++]) + 1; ++ while (task.cmdline[i] && bytes > 1) { ++ const int len = snprintf(str, bytes, "%s%s", i ? " " : "", task.cmdline[i]); ++ if (len < 0) { ++ *str = '\0'; ++ break; ++ } ++ if (len >= bytes) { ++ break; ++ } ++ str += len; ++ bytes -= len; ++ i++; + } + } else { + strcpy (cmd, task.cmd); diff -Nru procps-3.3.3/debian/patches/CVE-2018-1126.patch procps-3.3.3/debian/patches/CVE-2018-1126.patch --- procps-3.3.3/debian/patches/CVE-2018-1126.patch 1970-01-01 00:00:00.000000000 +0000 +++ procps-3.3.3/debian/patches/CVE-2018-1126.patch 2018-05-30 16:49:19.000000000 +0000 @@ -0,0 +1,83 @@ +Description: CVE-2018-1126 + procps-ng is vulnerable to an incorrect integer size in proc/alloc.* leading to + truncation/integer overflow issues. This flaw is related to CVE-2018-1124. + +Author: Abhijith PA <abhij...@disroot.org> +Origin: backported from procps-2:3.3.9-9+deb8u1 jessie. +Bug-Debian: https://bugs.debian.org/899170 +Last-Update: 2018-05-30 + +--- procps-3.3.3.orig/proc/alloc.c ++++ procps-3.3.3/proc/alloc.c +@@ -37,14 +37,14 @@ static void xdefault_error(const char *r + message_fn xalloc_err_handler = xdefault_error; + + +-void *xcalloc(unsigned int size) { ++void *xcalloc(size_t size) { + void * p; + + if (size == 0) + ++size; + p = calloc(1, size); + if (!p) { +- xalloc_err_handler("%s failed to allocate %u bytes of memory", __func__, size); ++ xalloc_err_handler("%s failed to allocate %zu bytes of memory", __func__, size); + exit(EXIT_FAILURE); + } + return p; +@@ -57,20 +57,20 @@ void *xmalloc(unsigned int size) { + ++size; + p = malloc(size); + if (!p) { +- xalloc_err_handler("%s failed to allocate %u bytes of memory", __func__, size); ++ xalloc_err_handler("%s failed to allocate %zu bytes of memory", __func__, size); + exit(EXIT_FAILURE); + } + return(p); + } + +-void *xrealloc(void *oldp, unsigned int size) { ++void *xrealloc(void *oldp, size_t size) { + void *p; + + if (size == 0) + ++size; + p = realloc(oldp, size); + if (!p) { +- xalloc_err_handler("%s failed to allocate %u bytes of memory", __func__, size); ++ xalloc_err_handler("%s failed to allocate %zu bytes of memory", __func__, size); + exit(EXIT_FAILURE); + } + return(p); +@@ -80,10 +80,14 @@ char *xstrdup(const char *str) { + char *p = NULL; + + if (str) { +- unsigned int size = strlen(str) + 1; ++ size_t size = strlen(str) + 1; ++ if (size < 1) { ++ xalloc_err_handler("%s refused to allocate %zu bytes of memory", __func__, size); ++ exit(EXIT_FAILURE); ++ } + p = malloc(size); + if (!p) { +- xalloc_err_handler("%s failed to allocate %u bytes of memory", __func__, size); ++ xalloc_err_handler("%s failed to allocate %zu bytes of memory", __func__, size); + exit(EXIT_FAILURE); + } + strcpy(p, str); +--- procps-3.3.3.orig/proc/alloc.h ++++ procps-3.3.3/proc/alloc.h +@@ -8,9 +8,9 @@ EXTERN_C_BEGIN + /* change xalloc_err_handler to override the default fprintf(stderr... */ + extern message_fn xalloc_err_handler; + +-extern void *xcalloc(unsigned int size) MALLOC; ++extern void *xcalloc(size_t size) MALLOC; + extern void *xmalloc(unsigned int size) MALLOC; +-extern void *xrealloc(void *oldp, unsigned int size) MALLOC; ++extern void *xrealloc(void *oldp, size_t size) MALLOC; + extern char *xstrdup(const char *str) MALLOC; + + EXTERN_C_END diff -Nru procps-3.3.3/debian/patches/series procps-3.3.3/debian/patches/series --- procps-3.3.3/debian/patches/series 2013-03-28 10:14:25.000000000 +0000 +++ procps-3.3.3/debian/patches/series 2018-05-30 16:49:18.000000000 +0000 @@ -3,3 +3,8 @@ watch_8bit uptime_test bts702965-biggerbuff +CVE-2018-1122.patch +CVE-2018-1123.patch +CVE-2018-1124.patch +CVE-2018-1125.patch +CVE-2018-1126.patch