Bug#212541: libc6: Group with many users makes processes loop and consume all memory
Package: libc6
Version: 2.3.2-8
Severity: critical
Tags: sarge sid
When I create a group with a lot of users some processes loop trying to
parse /etc/group and consume all available memory until they are killed.
You can reproduce this the following way:
# (echo -n testgrp1:x:65530:; for i in `seq 92`; do echo -n user$i,;
done; echo root) >> /etc/group
# grep testgrp1 /etc/group | wc
1 1 657
Then try to change the group of a file to a group that does not exist:
# touch /tmp/grptest1
# strace chgrp doesnotexist /tmp/grptest1 2>strace.log
The process is consuming all CPU time and using more and more memory.
strace.log shows that it is always repeating these steps:
open("/etc/group", O_RDONLY) = 3
fcntl64(3, F_GETFD) = 0
fcntl64(3, F_SETFD, FD_CLOEXEC) = 0
_llseek(3, 0, [0], SEEK_CUR) = 0
fstat64(3, {st_mode=S_IFREG|0644, st_size=2879, ...}) = 0
mmap2(NULL, 2879, PROT_READ, MAP_SHARED, 3, 0) = 0x40016000
_llseek(3, 2879, [2879], SEEK_SET) = 0
fstat64(3, {st_mode=S_IFREG|0644, st_size=2879, ...}) = 0
munmap(0x40016000, 2879) = 0
close(3) = 0
When the group does exist, chgrp works fine. If you remove the root user
from the testgrp1 it also works again:
# chgrp testgrp1 /tmp/grptest1
# vi /etc/group # remove root from testgrp1
# grep testgrp1 /etc/group | wc
1 1 652
# chgrp doesnotexist /tmp/grptest1
chgrp: invalid group name `doesnotexist'
The problem doesn't seem to be the number of users in a group, it looks
like it's the length of a line in /etc/group. For example, creating a
group with 26 long user names also triggers the problem:
# (echo -n testgrp2:x:65531:; for i in `seq 26`; do echo -n
someusersmighthaveaprettylongname$i,; done; echo root) >> /etc/group
# grep testgrp2 /etc/group | wc
1 1 949
Removing the "someusersmighthaveaprettylongname26" user also makes the
problem disappear:
# grep testgrp2 /etc/group | wc
1 1 913
The problem is not only triggered in chgrp, but also in ls, tar, mysql
and other programs that might look up non existing groups in /etc/group:
# touch /tmp/grptest2
# chgrp 65532 /tmp/grptest2
Add a long line to /etc/group (as above), gid 65532 must not exist:
# ls -l
I can reproduce this on a testing machine running
kernel-image-2.4.22-1-k7 and libc6 2.3.2-7 and also on an unstable
system running kernel 2.4.22-3um (User Mode Linux) and libc6 2.3.2-8.
The problem did not occur with glibc 2.3.1 which has been in testing before.
(Serverity critical because it breaks the whole system and might cause
data loss if the kernel's OOM handler kills the "wrong" processes.)
Reply to: