Package: procps
Version: 1:3.2.8-9squeeze1
Severity: normal

We found that under the following circumstances:
* Kernel > 3.2.29 (which shows > 32 groups in /proc/${pid}/status)
* one or more users logged in with lots of supplementary groups

then ps(1) fails with a SIGSEGV after attempting to allocate lots of memory.

This appears to be due flawed assumption in ps: That the contents of
/proc/${pid}/status will fit into a buffer of 1024 bytes: if the file
is larger, only the first 1024 bytes are read, and when subsequently
scanning the buffer the code "falls off the end":

  http://forums.grsecurity.net/viewtopic.php?f=3&t=3298

Although 32 groups sounds ample, sites using Active Directory will
often find their users being members of lots of groups, as group
membership is a recursive concept in AD. And the numeric group IDs are
(in our case) 9 characters each, thus easily overflowing the 1024 byte
buffer.

Here's an example:

----------------------------- 8< cut here 8< -----------------
karl@someserver: ~$ ps


Signal 11 (SEGV) caught by ps (procps version 3.2.8).
Please send bug reports to <feedb...@lists.sf.net> or <alb...@users.sf.net>
karl@someserver: ~$ strace ps 2>&1 | tail -30
stat("/proc/1997", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
open("/proc/1997/stat", O_RDONLY)       = 6
read(6, "1997 (sshd) S 1989 1989 1989 0 -"..., 1023) = 191
close(6)                                = 0
open("/proc/1997/status", O_RDONLY)     = 6
read(6, "Name:\tsshd\nState:\tS (sleeping)\nT"..., 1023) = 1023
close(6)                                = 0
mmap(NULL, 135168, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 
0x7f037a2fd000
mremap(0x7f037a2fd000, 135168, 266240, MREMAP_MAYMOVE) = 0x7f0379cd9000
mremap(0x7f0379cd9000, 266240, 528384, MREMAP_MAYMOVE) = 0x7f0379c58000
mremap(0x7f0379c58000, 528384, 1052672, MREMAP_MAYMOVE) = 0x7f0379b57000
mremap(0x7f0379b57000, 1052672, 2101248, MREMAP_MAYMOVE) = 0x7f0379956000
mremap(0x7f0379956000, 2101248, 4198400, MREMAP_MAYMOVE) = 0x7f0379555000
mremap(0x7f0379555000, 4198400, 8392704, MREMAP_MAYMOVE) = 0x7f0378d54000
mremap(0x7f0378d54000, 8392704, 16781312, MREMAP_MAYMOVE) = 0x7f0377d53000
mremap(0x7f0377d53000, 16781312, 33558528, MREMAP_MAYMOVE) = 0x7f0375d52000
mremap(0x7f0375d52000, 33558528, 67112960, MREMAP_MAYMOVE) = 0x7f0371d51000
mremap(0x7f0371d51000, 67112960, 134221824, MREMAP_MAYMOVE) = 0x7f0369d50000
mremap(0x7f0369d50000, 134221824, 268439552, MREMAP_MAYMOVE) = 0x7f0359d4f000
mremap(0x7f0359d4f000, 268439552, 536875008, MREMAP_MAYMOVE) = 0x7f0339d4e000
mremap(0x7f0339d4e000, 536875008, 1073745920, MREMAP_MAYMOVE) = 0x7f02f9d4d000
mremap(0x7f02f9d4d000, 1073745920, 2147487744, MREMAP_MAYMOVE) = 0x7f0279d4c000
mremap(0x7f0279d4c000, 2147487744, 4096, MREMAP_MAYMOVE) = 0x7f0279d4c000
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
write(2, "\n\nSignal 11 (SEGV) caught by ps "..., 132

Signal 11 (SEGV) caught by ps (procps version 3.2.8).
Please send bug reports to <feedb...@lists.sf.net> or <alb...@users.sf.net>
) = 132
exit_group(139)                         = ?


karl@someserver: ~$ wc --bytes < /proc/1997/status
1810
----------------------------- 8< cut here 8< -----------------

I have a (temporary) patch which increases the buffer size to 8K,
which appears sufficient in our case. But this does not fix the
underlying problem of having a limited buffer size to start with...


----------------------------- 8< cut here 8< -----------------
--- a/proc/readproc.c   2013-03-12 19:43:24.000000000 +0000
+++ b/proc/readproc.c   2013-03-13 10:12:47.744038428 +0000
@@ -28,6 +28,15 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 
+/* Max # of bytes to expect in /proc/%d/status.
+
+   This may be a crazy amount if lots of supplementary groups are
+   listed.  Most kernels will limit the contents to 32 (NGROUPS_SMALL)
+   groups, but kernels > 3.2.29 may show ALL of the supplementary
+   groups...
+ */
+#define PROC_STATUS_BUFSIZE 8192
+
 // sometimes it's easier to do this manually, w/o gcc helping
 #ifdef PROF
 extern void __cyg_profile_func_enter(void*,void*);
@@ -560,7 +569,7 @@
 // room to spare.
 static proc_t* simple_readproc(PROCTAB *restrict const PT, proc_t *restrict 
const p) {
     static struct stat sb;             // stat() buffer
-    static char sbuf[1024];    // buffer for stat,statm
+    static char sbuf[PROC_STATUS_BUFSIZE];     // buffer for stat,statm,status
     char *restrict const path = PT->path;
     unsigned flags = PT->flags;
 
@@ -655,7 +664,7 @@
 // path is a path to the task, with some room to spare.
 static proc_t* simple_readtask(PROCTAB *restrict const PT, const proc_t 
*restrict const p, proc_t *restrict const t, char *restrict const path) {
     static struct stat sb;             // stat() buffer
-    static char sbuf[1024];    // buffer for stat,statm
+    static char sbuf[PROC_STATUS_BUFSIZE];     // buffer for stat,statm,status
     unsigned flags = PT->flags;
 
 //printf("hhh\n");
@@ -1108,7 +1117,7 @@
  * and filled out proc_t structure.
  */
 proc_t * get_proc_stats(pid_t pid, proc_t *p) {
-       static char path[32], sbuf[1024];
+       static char path[32], sbuf[PROC_STATUS_BUFSIZE]; // buffer for 
stat,statm,status
        struct stat statbuf;
 
        sprintf(path, "/proc/%d", pid);
----------------------------- 8< cut here 8< -----------------


-- System Information:
Debian Release: 6.0.6
  APT prefers stable
  APT policy: (500, 'stable')
Architecture: amd64 (x86_64)

Kernel: Linux 3.2.0-0.bpo.4-amd64 (SMP w/2 CPU cores)
Locale: LANG=en_GB.utf8, LC_CTYPE=en_GB.utf8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash

Versions of packages procps depends on:
ii  initscripts        2.88dsf-13.1+squeeze1 scripts for initializing and shutt
ii  libc6              2.11.3-4              Embedded GNU C Library: Shared lib
ii  libncurses5        5.7+20100313-5        shared libraries for terminal hand
ii  libncursesw5       5.7+20100313-5        shared libraries for terminal hand
ii  lsb-base           3.2-23.2squeeze1      Linux Standard Base 3.2 init scrip

Versions of packages procps recommends:
ii  psmisc                   22.16-1~bpo60+1 utilities that use the proc file s

procps suggests no packages.

-- Configuration Files:
/etc/sysctl.conf changed [not included]

-- no debconf information


-- 
To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org
with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org

Reply via email to