reassign 553344 libc6 2.9-27 retitle 553344 libc6: getgrent() should not pass ERANGE from NSS module with NSS_STATUS_TRYAGAIN thanks On Fri, 2009-10-30 at 12:58 +0000, Adrian Bridgett wrote: > Using the test code attached (to track down what was a bug in > libnss-ldap), errno is being set after a specific getgrent call. > > There are 214 people in the group, totalling 4164 bytes so this may > well just be a "too large" error coming back (no other group > complains, but this is probably the longest group). Thanks for your bugreport. I think this is a bug in glibc. What happens is that the buffer that is used to store the group information is too small to fit all the group members. The NSS module tells this to glibc by returning NSS_STATUS_TRYAGAIN and setting errno to ERANGE, see: http://www.gnu.org/s/libc/manual/html_node/NSS-Modules-Interface.html Glibc then grows the buffer and calls the NSS module again but the errno from the first failed call is not cleared. libnss-ldapd only touches the returned errno if something went wrong (I believe this to be correct behaviour). This also happens when a large group is defined in /etc/group so it is not specific to libnss-ldapd. Note that the buffer is never shrunk so this only happens on the first call and not on the second run of your test program. I think glibc should not pass the errno set by the NSS module to the user if it was just a mechanism to signal that the buffer should be grown (and glibc did grow the buffer) or reset errno to the previous value on retry. Anyway, attached is a test program that shows the problem a little clearer. You need a large group (with say 100 members) to test this. In my test environment this prints: getgrent(): group "root", 0 members getgrent(): group "daemon", 0 members [...] getgrent(): group "testgroup", 2 members getgrent(): group "largegroup", 100 members errno=34 ("Numerical result out of range") getgrent(): group "hugegroup", 1000 members errno=34 ("Numerical result out of range") getgrent(): group "users", 2 members getgrent(): group "testgroup2", 2 members Test performed with both libc6 2.9-27 and 2.10.1-3, nscd not running. Btw, this may be in some ways related to bug #468378. -- -- arthur - adejong@debian.org - http://people.debian.org/~adejong --
#include <sys/types.h> #include <grp.h> #include <stdio.h> #include <errno.h> main() { int c; struct group * group; errno=0; while(group=getgrent()) { for (c=0;group->gr_mem[c]!=NULL;c++); printf("getgrent(): group \"%s\", %d members",group->gr_name,c); if (errno) printf(" errno=%d (\"%s\")",errno,strerror(errno)); printf("\n"); errno=0; } }
Attachment:
signature.asc
Description: This is a digitally signed message part