CLD-404 Details
Other IDs this deficiency may be known by:
Basic Information:
Affected Package(s) |
procps-ng |
Deficiency Type |
SECURITY |
Date Created |
2018-05-17 13:20:34 |
Date Last Modified |
2018-05-17 17:44:46 |
Version Specific Information:
Cucumber 1.0 i686 | fixed in procps-ng-3.3.11-i686-2 |
Cucumber 1.0 x86_64 | fixed in procps-ng-3.3.11-x86_64-2 and procps-ng-lib_i686-3.3.11-lib_i686-2 |
Cucumber 1.1 i686 |
fixed in procps-ng-3.3.11-i686-2 |
Cucumber 1.1 x86_64 |
fixed in procps-ng-3.3.11-x86_64-2 and procps-ng-lib_i686-3.3.11-lib_i686-2 |
Details:
=================================== Overview ===================================
An attacker can overflow the output buffer of ps, when executed by
another user, administrator, or script: a denial of service only (not
an LPE), because ps mmap()s its output buffer and mprotect()s its last
page with PROT_NONE (an effective guard page).
================================ Initial Report ================================
From http://www.openwall.com/lists/oss-security/2018/05/17/1:
ps's functions pr_args(), pr_comm(), and pr_fname() are vulnerable to an
mmap-based buffer overflow of outbuf (ps's output buffer):
401 static int pr_args(char *restrict const outbuf, const proc_t *restrict const pp){
402 char *endp = outbuf;
403 int rightward = max_rightward;
404 int fh = forest_helper(outbuf);
405
406 endp += fh;
407 rightward -= fh;
408
409 if(pp->cmdline && !bsd_c_option)
410 endp += escaped_copy(endp, *pp->cmdline, OUTBUF_SIZE, &rightward);
411 else
412 endp += escape_command(endp, pp, OUTBUF_SIZE, &rightward, ESC_DEFUNCT);
413
414 if(bsd_e_option && rightward>1) {
415 if(pp->environ && *pp->environ) {
416 *endp++ = ' ';
417 rightward--;
418 endp += escape_strlist(endp, pp->environ, OUTBUF_SIZE, &rightward);
419 }
420 }
421 return max_rightward-rightward;
422 }
The number of bytes written to endp by the escape*() functions is added
to endp (a pointer into outbuf), but never subtracted from OUTBUF_SIZE.
Normally "rightward" prevents this buffer overflow, because the maximum
number of "cells" written to outbuf is OUTBUF_SIZE, and is equal to the
number of "bytes" written to outbuf; but not in escape_str_utf8():
36 static int escape_str_utf8(char *restrict dst, const char *restrict src, int bufsize, int *maxcells){
..
50 if (!(len = mbrtowc (&wc, src, MB_CUR_MAX, &s)))
..
78 int wlen = wcwidth(wc);
..
100 memcpy(dst, src, len);
101 my_cells += wlen;
102 dst += len;
103 my_bytes += len;
104 src += len;
For example, in the "en_US.UTF-8" locale, the multibyte sequence
"\xf4\x81\x8e\xb6" consumes 4 bytes, but only 1 cell, and an easy
trigger for one of the outbuf overflows is:
$ (A=`python -c 'print "\xf4\x81\x8e\xb6" * 32767'` exec -a `python -c 'print "A" * 65535'` sleep 60) &
[1] 2670
# env LANG=en_US.UTF-8 ps awwe
PID TTY STAT TIME COMMAND
...
Signal 11 (SEGV) caught by ps (procps-ng version 3.3.10).
2670 pts/0 S 0:00ps:display.c:66: please report this bug
Segmentation fault
This buffer overflow is a denial of service only (not an LPE), because
ps mmap()s outbuf and mprotect()s its last page with PROT_NONE (an
effective guard page):
2147 void init_output(void){
....
2164 outbuf = mmap(
2165 0,
2166 page_size * (outbuf_pages+1), // 1 more, for guard page at high addresses
2167 PROT_READ | PROT_WRITE,
2168 MAP_PRIVATE | MAP_ANONYMOUS,
2169 -1,
2170 0
2171 );
....
2174 mprotect(outbuf + page_size*outbuf_pages, page_size, PROT_NONE); // guard page
================================= Our Analysis =================================
Fixed in patch 0054-ps-output.c-Fix-outbuf-overflows-in-pr_args-etc.patch
https://www.qualys.com/2018/05/17/procps-ng-audit-report-patches.tar.gz
================================= Our Solution =================================
We have applied the aforementioned patch and rebuilt