Similar to bug 10203 (http://sources.redhat.com/bugzilla/show_bug.cgi?id=10203). When the name server switch gets configured for NIS: group: nis files and the group map is larger than MINSIZE, _nis_saveit in nis/nss_nis/nis-pwd.c allocates linked blocks with intern.start pointing at the first block. internal_nis_setgrent() initially sets intern.next to intern.start. Currently, internal_nis_endgrent() uses intern.next as the starting block to iterate over the chain when free'ing blocks. When getgrent() gets called, however, intern.next can be reset to another block in the chain. As a result, the following program will cause allocated blocks to be never be free'd since in this case intern.next points at the last block and the "next" pointer on this block is set to NULL. #include <sys/types.h> #include <grp.h> #include <stdio.h> main(){ struct group *gp; while( gp = getgrent()){ printf("%s %d\n", gp->gr_name, gp->gr_gid); } endgrent(); } After internal_nis_endgrent(), sets intern.next and intern.start to NULL, the other allocated blocks on the chain are irretrievably lost. This issue exists in other releases prior to glibc-2.10, including glibc-2.5 on RHEL 5.3. The easiest fix is to make internal_nis_endgrent() use intern.start directly instead of intern.next. diff -urNp a/nis/nss_nis/nis-grp.c b/nis/nss_nis/nis-grp.c --- a/nis/nss_nis/nis-grp.c 2009-09-30 16:58:01.000000000 -0700 +++ b/nis/nss_nis/nis-grp.c 2009-09-30 16:59:21.000000000 -0700 @@ -55,7 +55,7 @@ internal_nis_endgrent (void) oldkeylen = 0; } - struct response_t *curr = intern.next; + struct response_t *curr = intern.start; while (curr != NULL) { Thanks, Joe
Created attachment 4238 [details] Proposed patch Attach proposed patch.
I applied the patch.