procps
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 <abhijith@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 <abhijith@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 <abhijith@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 <abhijith@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 <abhijith@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 <abhijith@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
Reply to:
- Follow-Ups:
- Re: procps
- From: Holger Levsen <holger@layer-acht.org>
- Re: procps
- From: Holger Levsen <holger@layer-acht.org>