[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: Bug#553344: libnss-ldapd: errno 34 set



On Sun, Nov 01, 2009 at 12:44:20PM +0100, Arthur de Jong wrote:
> 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.
> 

The bug is actually in the testcase. errno value only makes sense when
there is an error, so it should be checked only when the return value of
getgrent() is NULL.

-- 
Aurelien Jarno                          GPG: 1024D/F1BCDB73
aurelien@aurel32.net                 http://www.aurel32.net


Reply to: