makedbm allows NIS group records of 1024 bytes to create glibc error on NIS clients Description of problem: Group records of exactly 1024 bytes in /etc/group of a NIS master server causes 5.2/5.3 NIS clients to error when using getgrent(). Version-Release number of selected component (if applicable): On 5.3 glibc-2.5-34 ypserv-2.19-5.el5 ypbind-1.19-11.el5 On 5.2 glibc-2.5-24.el5_2.2 ypbind-1.19-8.el5 On 4.7 things seemed to work. How reproducible: Easy to reproduce once a test environment is set up. Steps to Reproduce: 1. Set up NIS master with latest 5.3 ypserv 2. Set up NIS clients with latest 5.3 glibc and ypbind to the above NIS master 3. Create a group record of exactly 1024 bytes in the master server's /etc/group. The following should generate such a line in /tmp/bar1024. bash -c 'echo -n crashgroup1:x:12345: ; let uno=0 ; while [ $uno -le 100 ] ; do echo -n usernam$uno, ; let uno=$uno+1 ; done ; echo foo' > /tmp/bar1024 4. Compile and run the following bit of C on a NIS client: #include <sys/types.h> #include <grp.h> #include <stdio.h> main(){ struct group *gp; while( gp = getgrent()){ printf("%d\n", gp->gr_gid); } } 5. Observe glibc failure (below). Actual results: $ ./a.out >& getgrent.error.out *** glibc detected *** ./a.out: munmap_chunk(): invalid pointer: 0x0880517a *** ======= Backtrace: ========= /lib/libc.so.6(cfree+0x1bb)[0x16dceb] /lib/libnss_nis.so.2(_nss_nis_getgrent_r+0x2ad)[0x44619d] /lib/libc.so.6[0x1e444e] /lib/libc.so.6(getgrent_r+0xad)[0x18fdcd] /lib/libc.so.6[0x1e4016] /lib/libc.so.6(getgrent+0x71)[0x18f7a1] ./a.out[0x80483e2] /lib/libc.so.6(__libc_start_main+0xdc)[0x116e8c] ./a.out[0x8048301] ======= Memory map: ======== 00101000-0023f000 r-xp 00000000 fd:00 22872116 /lib/libc-2.5.so 0023f000-00241000 r-xp 0013e000 fd:00 22872116 /lib/libc-2.5.so 00241000-00242000 rwxp 00140000 fd:00 22872116 /lib/libc-2.5.so 00242000-00245000 rwxp 00242000 00:00 0 0025d000-0025e000 r-xp 0025d000 00:00 0 [vdso] 003ff000-0040a000 r-xp 00000000 fd:00 22872211 /lib/libgcc_s-4.1.2-20080825.so.1 0040a000-0040b000 rwxp 0000a000 fd:00 22872211 /lib/libgcc_s-4.1.2-20080825.so.1 00417000-00431000 r-xp 00000000 fd:00 22872102 /lib/ld-2.5.so 00431000-00432000 r-xp 00019000 fd:00 22872102 /lib/ld-2.5.so 00432000-00433000 rwxp 0001a000 fd:00 22872102 /lib/ld-2.5.so 00435000-0043e000 r-xp 00000000 fd:00 22872272 /lib/libnss_files-2.5.so 0043e000-0043f000 r-xp 00008000 fd:00 22872272 /lib/libnss_files-2.5.so 0043f000-00440000 rwxp 00009000 fd:00 22872272 /lib/libnss_files-2.5.so 00442000-0044a000 r-xp 00000000 fd:00 22872286 /lib/libnss_nis-2.5.so 0044a000-0044b000 r-xp 00007000 fd:00 22872286 /lib/libnss_nis-2.5.so 0044b000-0044c000 rwxp 00008000 fd:00 22872286 /lib/libnss_nis-2.5.so 04ee3000-04ef6000 r-xp 00000000 fd:00 22872215 /lib/libnsl-2.5.so 04ef6000-04ef7000 r-xp 00012000 fd:00 22872215 /lib/libnsl-2.5.so 04ef7000-04ef8000 rwxp 00013000 fd:00 22872215 /lib/libnsl-2.5.so 04ef8000-04efa000 rwxp 04ef8000 00:00 0 08048000-08049000 r-xp 00000000 00:1e 12061834 /u/jack/a.out 08049000-0804a000 rw-p 00000000 00:1e 12061834 /u/jack/a.out 08801000-08822000 rw-p 08801000 00:00 0 [heap] b7f46000-b7f4a000 rw-p b7f46000 00:00 0 bff0c000-bff21000 rw-p bffea000 00:00 0 [stack] Aborted (core dumped) Expected results: A successful listing of group ids. Additional info: I'm not sure whether this is a ypserv problem, a glibc problem or both. makedbm will issue a 'warning' and then kindly omit any group record over 1024 bytes. I'd probably prefer it just truncate the entry while giving said warning instead of omitting it, but I haven't researched "proper" behavior in that instance. In any case... These two lines in makedbm.c should probably use greater than or equal (>=) to allow for any null string terminator: 409: if (check_limit && strlen (key) > YPMAXRECORD) 417: if (check_limit && strlen (cptr) > YPMAXRECORD) (where YPMAXRECORD=1024) because glibc has something like this: ./grp/grp.h:# define NSS_BUFLEN_GROUP 1024 Also, there should probably be some forced null termination or restricted read buffer before that. I'm not sure if glibc's barfing on bad data is glibc's problem or not. getgrent() is provided by glibc. There may be other facilities that fail to provide null terminated strings that could cause glibc group lookup to fail. Perhaps it could fail better?
Thank you for the great analysis. I sent an email about this to ypserv upstream, as I also think that makedbm.c should check the limit using >=.
This request was evaluated by Red Hat Product Management for inclusion in the current release of Red Hat Enterprise Linux. Because the affected component is not scheduled to be updated in the current release, Red Hat is unfortunately unable to address this request at this time. Red Hat invites you to ask your support representative to propose this request, if appropriate and relevant, in the next release of Red Hat Enterprise Linux.
This request was erroneously denied for the current release of Red Hat Enterprise Linux. The error has been fixed and this request has been re-proposed for the current release.
Upstream bug and commit: http://sourceware.org/bugzilla/show_bug.cgi?id=10692 http://sourceware.org/git/?p=glibc.git;a=commitdiff;h=c240c3a58f21d72982e74a485bd7c4900f188876
This request was evaluated by Red Hat Product Management for inclusion in a Red Hat Enterprise Linux release. Product Management has requested further review of this request by Red Hat Engineering, for potential inclusion in a Red Hat Enterprise Linux release for currently deployed products. This request is not yet committed for inclusion in a release.
Technical note added. If any revisions are required, please edit the "Technical Notes" field accordingly. All revisions will be proofread by the Engineering Content Services team. New Contents: The glibc function getgrent() would incorrectly generate an error when a 1024 byte Network Information Services (NIS) group record was requested from the NIS master server. This was caused by an attempt to free an unallocated pointer on batch_read's. getgrent() now functions as expected and does not return an error for this case.
Since the problem described in this bug report should be resolved in a recent advisory, it has been closed with a resolution of ERRATA. For information on the advisory, and where to find the updated files, follow the link below. If the solution does not work for you, open a new bug report. http://rhn.redhat.com/errata/RHBA-2013-0022.html