Comment 1 for bug 1150413

Andrew Lowther (alowther) wrote :

I'm not sure the best way to fix this, but I have located the problem.

I've found this bug to be caused by a Debian patch "ps_supgid_display.patch" which was initially from the bug report at http://bugs.debian.org/506303

When any /proc/<pid>/status has more than 1024 characters before the end of the Groups line, an infinite loop is entered because the loop never finds the "\n" character it expected. Looking back at the strace, the read of "/proc/11860/status" is truncated. A succesful part of the strace is

stat("/proc/1110", {st_mode=S_IFDIR|0555, st_size=0, ...}) = 0
open("/proc/1110/stat", O_RDONLY) = 6
read(6, "1110 (npcd) S 1 1108 1108 0 -1 4202816 509903 56395239 0 129102 205 836 161563 37679 20 0 1 0 3191 243957760 263 18446744073709551615 4194304 4219268 140737259370048 140737259368256 140200938633277 0 0 0 16387 18446744071579436968 0 0 17 0 0 0 1348 0 0\n", 1023) = 253

While the loop runs, it keeps allocating more memory for the array of Group IDs that it has found associated with the process until it fails because there isn't enough memory to allocate.

The while loop below from the patch is what runs infinitely. The xrealloc allocates more memory, doubling the amount it wants each time the loop thinks the array is filled.
+ case_Groups:
+ isupgid = 0;
+ if (*S != '\n'){ // Is there any supplementary group ?
+ P->supgid = (int *) xmalloc(0x0004 * sizeof(int));
+ int vctsize = 0x0004;
+ while (S[1] != '\n' && isupgid<INT_MAX){ // There is one blank before '\n'
+ if (isupgid == vctsize){
+ vctsize *= 2;
+ P->supgid = (int *)xrealloc(P->supgid,vctsize * sizeof(int));
+ }
+ P->supgid[isupgid++] = strtol(S,&S,10);
+ P->nsupgid++;
+ }
+ }
+ continue;