diff -Nru procps-3.2.8/debian/changelog procps-3.2.8/debian/changelog --- procps-3.2.8/debian/changelog 2011-12-12 11:33:32.000000000 -0600 +++ procps-3.2.8/debian/changelog 2013-09-25 16:52:55.000000000 -0500 @@ -1,3 +1,12 @@ +procps (1:3.2.8-11ubuntu6.1) precise; urgency=low + + * Backport of a45dace4 and 95d01362 in order to enable dynamically + allocated buffers in file2str. This fixes a number of seg fault problems + including the one related to large numbers of groups per user. + (LP: #1150413) + + -- Dave Chiluk Wed, 25 Sep 2013 16:52:40 -0500 + procps (1:3.2.8-11ubuntu6) precise; urgency=low * debian/sysctl.d/10-zeroconf ... have armhf using teh same value that diff -Nru procps-3.2.8/debian/patches/dynamic_file2str.patch procps-3.2.8/debian/patches/dynamic_file2str.patch --- procps-3.2.8/debian/patches/dynamic_file2str.patch 1969-12-31 18:00:00.000000000 -0600 +++ procps-3.2.8/debian/patches/dynamic_file2str.patch 2013-09-25 16:53:38.000000000 -0500 @@ -0,0 +1,253 @@ +Description: Enables file2str to use dynamic buffers instead of static 1024 + Backport of a45dace4 and 95d01362 in order to enable dynamically + allocated buffers in file2str. This fixes a number of seg fault problems + including the one related to large numbers of groups per user. + +Author: Dave Chiluk +Bug-Ubuntu: https://bugs.launchpad.net/bugs/1150413 +Origin: upstream, https://gitorious.org/procps/procps/commit/a45dace4b82c9cdcda7020ca5665153b1e81275f, https://gitorious.org/procps/procps/commit/95d0136281ec00c68e2994d708fec4dd28275453 +--- procps-3.2.8.orig/proc/readproc.c ++++ procps-3.2.8/proc/readproc.c +@@ -38,6 +38,14 @@ extern void __cyg_profile_func_enter(voi + #define LEAVE(x) + #endif + ++// dynamic 'utility' buffer support for file2str() calls ++struct utlbuf_s { ++ char *buf; // dynamically grown buffer ++ int siz; // current len of the above ++} utlbuf_s; ++ ++#ifdef SIGNAL_STRING ++#else + // convert hex string to unsigned long long + static unsigned long long unhex(const char *restrict cp){ + unsigned long long ull = 0; +@@ -48,6 +56,8 @@ static unsigned long long unhex(const ch + } + return ull; + } ++#endif ++ + + static int task_dir_missing; + +@@ -287,7 +297,8 @@ ENTER(0x220); + if (*S != '\n'){ // Is there any supplementary group ? + P->supgid = (int *) xmalloc(0x0004 * sizeof(int)); + int vctsize = 0x0004; +- while (S[1] != '\n' && isupgidsupgid = (int *)xrealloc(P->supgid,vctsize * sizeof(int)); +@@ -433,18 +444,29 @@ static void statm2proc(const char* s, pr + /* fprintf(stderr, "statm2proc converted %d fields.\n",num); */ + } + +-static int file2str(const char *directory, const char *what, char *ret, int cap) { +- static char filename[80]; +- int fd, num_read; +- +- sprintf(filename, "%s/%s", directory, what); +- fd = open(filename, O_RDONLY, 0); +- if(unlikely(fd==-1)) return -1; +- num_read = read(fd, ret, cap - 1); ++static int file2str(const char *directory, const char *what, struct utlbuf_s *ub) { ++ #define buffGRW 1024 ++ char path[PROCPATHLEN]; ++ int fd, num, tot_read = 0; ++ ++ ++ /* on first use we preallocate a buffer of minimum size to emulate ++ former 'local static' behavior -- even if this read fails, that ++ buffer will likely soon be used for another subdirectory anyway ++ ( besides, with this xcalloc we will never need to use memcpy ) */ ++ if (ub->buf) ub->buf[0] = '\0'; ++ else ub->buf = xmalloc((ub->siz = buffGRW)); ++ sprintf(path, "%s/%s", directory, what); ++ if (-1 == (fd = open(path, O_RDONLY, 0))) return -1; ++ while (0 < (num = read(fd, ub->buf + tot_read, ub->siz - tot_read))) { ++ tot_read += num; ++ if (tot_read < ub->siz) continue; ++ ub->buf = xrealloc(ub->buf, (ub->siz += buffGRW)); ++ }; ++ ub->buf[tot_read] = '\0'; + close(fd); +- if(unlikely(num_read<=0)) return -1; +- ret[num_read] = '\0'; +- return num_read; ++ return tot_read; ++ #undef buffGRW + } + + static char** file2strvec(const char* directory, const char* what) { +@@ -562,8 +584,8 @@ int read_cmdline(char *restrict const ds + // The pid (tgid? tid?) is already in p, and a path to it in path, with some + // room to spare. + static proc_t* simple_readproc(PROCTAB *restrict const PT, proc_t *restrict const p) { ++ static struct utlbuf_s ub = { NULL, 0 }; // buf for stat,statm,status + static struct stat sb; // stat() buffer +- static char sbuf[1024]; // buffer for stat,statm + char *restrict const path = PT->path; + unsigned flags = PT->flags; + +@@ -577,19 +599,19 @@ static proc_t* simple_readproc(PROCTAB * + p->egid = sb.st_gid; /* need a way to get real gid */ + + if (flags & PROC_FILLSTAT) { /* read, parse /proc/#/stat */ +- if (unlikely( file2str(path, "stat", sbuf, sizeof sbuf) == -1 )) ++ if (unlikely( file2str(path, "stat", &ub) == -1 )) + goto next_proc; /* error reading /proc/#/stat */ +- stat2proc(sbuf, p); /* parse /proc/#/stat */ ++ stat2proc(ub.buf, p); /* parse /proc/#/stat */ + } + + if (unlikely(flags & PROC_FILLMEM)) { /* read, parse /proc/#/statm */ +- if (likely( file2str(path, "statm", sbuf, sizeof sbuf) != -1 )) +- statm2proc(sbuf, p); /* ignore statm errors here */ ++ if (likely( file2str(path, "statm", &ub) != -1 )) ++ statm2proc(ub.buf, p); /* ignore statm errors here */ + } /* statm fields just zero */ + + if (flags & PROC_FILLSTATUS) { /* read, parse /proc/#/status */ +- if (likely( file2str(path, "status", sbuf, sizeof sbuf) != -1 )){ +- status2proc(sbuf, p, 1); ++ if (likely( file2str(path, "status", &ub) != -1 )){ ++ status2proc(ub.buf, p, 1); + } + } + +@@ -619,8 +641,8 @@ static proc_t* simple_readproc(PROCTAB * + } + + if (flags & PROC_FILLSUPGRP && p->nsupgid > 0){ ++ int i=0; + allocsupgrp(p); +- int i; + for (i=0; i < p->nsupgid; i++) + memcpy(p->supgrp[i], group_from_gid(p->supgid[i]), P_G_SZ); + } +@@ -657,8 +679,8 @@ next_proc: + // t is the POSIX thread (task group member, generally not the leader) + // 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 utlbuf_s ub = { NULL, 0 }; // buf for stat,statm,status + static struct stat sb; // stat() buffer +- static char sbuf[1024]; // buffer for stat,statm + unsigned flags = PT->flags; + + //printf("hhh\n"); +@@ -673,9 +695,9 @@ static proc_t* simple_readtask(PROCTAB * + + //printf("iii\n"); + if (flags & PROC_FILLSTAT) { /* read, parse /proc/#/stat */ +- if (unlikely( file2str(path, "stat", sbuf, sizeof sbuf) == -1 )) ++ if (unlikely( file2str(path, "stat", &ub) == -1 )) + goto next_task; /* error reading /proc/#/stat */ +- stat2proc(sbuf, t); /* parse /proc/#/stat */ ++ stat2proc(ub.buf, t); /* parse /proc/#/stat */ + } + + if (unlikely(flags & PROC_FILLMEM)) { /* read, parse /proc/#/statm */ +@@ -694,8 +716,8 @@ static proc_t* simple_readtask(PROCTAB * + } /* statm fields just zero */ + + if (flags & PROC_FILLSTATUS) { /* read, parse /proc/#/status */ +- if (likely( file2str(path, "status", sbuf, sizeof sbuf) != -1 )){ +- status2proc(sbuf, t, 0); ++ if (likely( file2str(path, "status", &ub) != -1 )){ ++ status2proc(ub.buf, t, 0); + } + } + +@@ -720,8 +742,8 @@ static proc_t* simple_readtask(PROCTAB * + } + + if (flags & PROC_FILLSUPGRP && t->nsupgid > 0){ ++ int i=0; + allocsupgrp(t); +- int i; + for (i=0; i < t->nsupgid; i++) + memcpy(t->supgrp[i], group_from_gid(t->supgid[i]), P_G_SZ); + } +@@ -944,16 +966,18 @@ void closeproc(PROCTAB* PT) { + + // allocate memory for supgrp + void allocsupgrp(proc_t *p) { ++ int i=0; ++ + if (!p || p->nsupgid == 0) return; + p->supgrp = (char**)xmalloc(p->nsupgid * sizeof(char*)); +- int i; + for (i=0; insupgid; i++) + p->supgrp[i] = (char*)xmalloc(P_G_SZ * sizeof(char)); + } + + // free memory allocated for supgrp + void freesupgrp(proc_t *p) { +- int i; ++ int i=0; ++ + for (i=0; insupgid; i++) + if (p->supgrp[i]) free(p->supgrp[i]); + free(p->supgrp); +@@ -977,13 +1001,14 @@ void freeproc(proc_t* p) { + + ////////////////////////////////////////////////////////////////////////////////// + void look_up_our_self(proc_t *p) { +- char sbuf[1024]; ++ struct utlbuf_s ub = { NULL, 0 }; + +- if(file2str("/proc/self", "stat", sbuf, sizeof sbuf) == -1){ ++ if(file2str("/proc/self", "stat", &ub) == -1){ + fprintf(stderr, "Error, do this: mount -t proc none /proc\n"); + _exit(47); + } +- stat2proc(sbuf, p); // parse /proc/self/stat ++ stat2proc(ub.buf, p); // parse /proc/self/stat ++ free(ub.buf); + } + + HIDDEN_ALIAS(readproc); +@@ -1111,21 +1136,23 @@ proc_data_t *readproctab2(int(*want_proc + * and filled out proc_t structure. + */ + proc_t * get_proc_stats(pid_t pid, proc_t *p) { +- static char path[32], sbuf[1024]; +- struct stat statbuf; ++ struct utlbuf_s ub = { NULL, 0 }; ++ static char path[32]; ++ struct stat statbuf; ++ ++ sprintf(path, "/proc/%d", pid); ++ if (stat(path, &statbuf)) { ++ perror("stat"); ++ return NULL; ++ } ++ ++ if (file2str(path, "stat", &ub) >= 0) ++ stat2proc(ub.buf, p); ++ if (file2str(path, "statm", &ub) >= 0) ++ statm2proc(ub.buf, p); ++ if (file2str(path, "status", &ub) >= 0) ++ status2proc(ub.buf, p, 0); + +- sprintf(path, "/proc/%d", pid); +- if (stat(path, &statbuf)) { +- perror("stat"); +- return NULL; +- } +- +- if (file2str(path, "stat", sbuf, sizeof sbuf) >= 0) +- stat2proc(sbuf, p); /* parse /proc/#/stat */ +- if (file2str(path, "statm", sbuf, sizeof sbuf) >= 0) +- statm2proc(sbuf, p); /* ignore statm errors here */ +- if (file2str(path, "status", sbuf, sizeof sbuf) >= 0) +- status2proc(sbuf, p, 0 /*FIXME*/); +- +- return p; ++ free(ub.buf); ++ return p; + } diff -Nru procps-3.2.8/debian/patches/series procps-3.2.8/debian/patches/series --- procps-3.2.8/debian/patches/series 2011-12-05 05:45:35.000000000 -0600 +++ procps-3.2.8/debian/patches/series 2013-09-25 16:53:22.000000000 -0500 @@ -73,3 +73,4 @@ btime_from_proc_stat.patch procps-3.2.7-top-clrscr.patch vmstat_truncate +dynamic_file2str.patch