Red Hat Bugzilla – Bug 1213603
glibc: nss_db: get*ent crashes without preceding set*ent
Last modified: 2017-08-01 14:06:55 EDT
Description of problem: Baseline, with nsswitch set to use db, but no .db files. This works: <snip> root@garabaldi ~]# grep services /etc/nsswitch.conf | grep -v '^#' services: db files sss [root@garabaldi ~]# rm -f /var/db/* rm: cannot remove ‘/var/db/sudo’: Is a directory [root@garabaldi ~]# perl -e getservent [root@garabaldi ~]# <snip> Now let;s build a default db file set (this is a clean install): <snip> [root@garabaldi ~]# perl -e getservent [root@garabaldi ~]# cd /var/db/; make; cd - passwd... done. group... done. protocols... done. rpc... done. services... done. shadow... done. Warning: The shadow password database /var/db/shadow.db has been set to be readable only by root. You may want to make it readable by the `shadow' group depending on your configuration. gshadow... done. Warning: The shadow group database /var/db/gshadow.db has been set to be readable only by root. You may want to make it readable by the `shadow' group depending on your configuration. /root [root@garabaldi ~]# perl -e getservent Segmentation fault <snip> Core was generated by `perl -e getservent'. Program terminated with signal 11, Segmentation fault. #0 0x00007f90955685bf in __rawmemchr_sse2 () from /lib64/libc.so.6 Missing separate debuginfos, use: debuginfo-install perl-5.16.3-285.el7.x86_64 (gdb) bt #0 0x00007f90955685bf in __rawmemchr_sse2 () from /lib64/libc.so.6 #1 0x00007f908eba81c1 in _nss_db_getservent_r () from /lib64/libnss_db.so.2 #2 0x00007f90955e0c11 in __nss_getent_r () from /lib64/libc.so.6 #3 0x00007f90955e983a in getservent_r@@GLIBC_2.2.5 () from /lib64/libc.so.6 #4 0x00007f9096931a96 in Perl_pp_gservent () from /usr/lib64/perl5/CORE/libperl.so #5 0x00007f90968dca46 in Perl_runops_standard () from /usr/lib64/perl5/CORE/libperl.so #6 0x00007f9096879855 in perl_run () from /usr/lib64/perl5/CORE/libperl.so #7 0x0000000000400d99 in main () <snip> Version-Release number of selected component (if applicable): glibc-2.17-78.el7.x86_64 How reproducible: Steps to Reproduce: 1. Set nsswitch to use 'db' for services > grep services /etc/nsswitch.conf | grep -v '^#' > services: db files sss 2. cd /var/db/; make; cd - 3. perl -e getservent Actual results: Segfault Expected results: No Segfault Additional info:
It appears the cause is that that implicit initialization of the service by get*ent (without a preceding set*ent) does not cause initialization of the entidex variable. _nss_db_get*_r does this: 247 if (state.header == NULL) 248 { 249 status = internal_setent (DBFILE, &state); 250 if (status != NSS_STATUS_SUCCESS) 251 { 252 *errnop = errno; 253 H_ERRNO_SET (NETDB_INTERNAL); 254 goto out; 255 } 256 } While _nss_db_set* has: 72 status = internal_setent (DBFILE, &state); 73 74 if (status == NSS_STATUS_SUCCESS) 75 { 76 /* Remember STAYOPEN flag. */ 77 keep_db |= stayopen; 78 79 /* Reset the sequential index. */ 80 entidx = (const char *) state.header + state.header->valstroffset; 81 } As far as I can see, the bug is present upstream as well.
Patch posted upstream: https://sourceware.org/ml/libc-alpha/2016-06/msg00346.html
Upstream fix: https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=31d0a4fa646db8b8c97ce24e0ec0a7b73de4fca1
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. https://access.redhat.com/errata/RHSA-2017:1916