From owner-freebsd-bugs Thu Jun 3 7:50: 7 1999 Delivered-To: freebsd-bugs@freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.ORG [204.216.27.21]) by hub.freebsd.org (Postfix) with ESMTP id E7372152A3 for ; Thu, 3 Jun 1999 07:50:01 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.9.3/8.9.2) id HAA94621; Thu, 3 Jun 1999 07:50:01 -0700 (PDT) (envelope-from gnats@FreeBSD.org) Received: from sivka.carrier.kiev.ua (zirafe.carrier.kiev.ua [193.193.193.119]) by hub.freebsd.org (Postfix) with ESMTP id B6F18153D2 for ; Thu, 3 Jun 1999 07:44:06 -0700 (PDT) (envelope-from netch@sivka.carrier.kiev.ua) Received: (from netch@localhost) by sivka.carrier.kiev.ua (8.Who.Cares/Kilkenny_is_better) id RAA84607; Thu, 3 Jun 1999 17:44:04 +0300 (EEST) (envelope-from netch) Message-Id: <199906031444.RAA84607@sivka.carrier.kiev.ua> Date: Thu, 3 Jun 1999 17:44:04 +0300 (EEST) From: netch@lucky.net (Valentin Nechayev) Reply-To: netch@lucky.net To: FreeBSD-gnats-submit@freebsd.org X-Send-Pr-Version: 3.2 Subject: bin/12008: getpwent() YP bug Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org >Number: 12008 >Category: bin >Synopsis: getpwent() YP bug >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Thu Jun 3 07:50:01 PDT 1999 >Closed-Date: >Last-Modified: >Originator: Valentin Nechayev >Release: FreeBSD 3.2-STABLE i386 >Organization: Lucky Net Ltd >Environment: FreeBSD 3.2-STABLE >Description: With YP/NIS or pseudo YP/NIS entries in password database, multiple setpwent() - getpwent() - endpwent() cycles result in null pointer usage with successive segmentation fault. YP support in getpwxxx() function group uses variable _yp_enabled to make decision in YP using policy. Its initial value (-1) causes getpwxxx() functions ( getpwnam, getpwuid, getpwent ) to call _ypinitdb(). _ypinitdb() creates cache DB in memory pointed by _ypcache pointer and changes _yp_enabled value to non-negative. When endpwent() called, it clears some variables and destruct the database, then _ypcache points to null, but _yp_enabled keeps its old state. When getpwent() is called after endpwent(), the following code is executed: ==== cut src/lib/libc/gen/getpwent.c line 122 === #ifdef YP if(_pw_passwd.pw_name[0] == '+' || _pw_passwd.pw_name[0] == '-') { if (_yp_enabled == -1) _ypinitdb(); bzero((char *)&_ypnam, sizeof(_ypnam)); bcopy(_pw_passwd.pw_name, _ypnam, strlen(_pw_passwd.pw_name)); _pw_copy = _pw_passwd; if (unwind((char *)&_ypnam) == 0) goto tryagain; else return(&_pw_passwd); } #else === end cut === In this code, _yp_enabled is not equal to -1, therefore _ypinitdb() is not called; when getpwent() calls unwind(), unwind calls store(), store tries to write data to cache database, but cache database does not exist and _ypcache is equal to NULL. SEGV. >How-To-Repeat: Add the following comment line to /etc/master.passwd: ---:-:8:8::0:0:------------ SLIRP pseudo-users ------------:/no.such/dir:/dev/null but really line content is IMHO insensitive, when it matches /^+/ or /^-/. Rebuild password databases using pwd_mkdb program or vipw editing interface. Compile and run the following program: === cut here === #include #include #include int main() { int i; for( i = 1; i <= 2; i++ ) { struct passwd* pwp; setpwent(); while( ( pwp = getpwent() ) != NULL ) ; endpwent(); } printf( "I am alive!\n" ); } === end cut === At second iteration of for(i), a segmentation fault occurs: === cut gdb output === Starting program: /usr/staff/netch/tmp/getpwbug/test2/test2 Program received signal SIGSEGV, Segmentation fault. 0x8049d43 in store (key=0x804ba25 "-") at getpwent.c:386 386 (void)(_ypcache->put)(_ypcache, &lkey, &empty, R_NOOVERWRITE); (gdb) print _ypcache $1 = (DB *) 0x0 === end cut === >Fix: Clear the variable _yp_enabled to default value (-1) when endpwent() clears _ypcache database: *** src/lib/libc/gen/getpwent.c.orig Thu Dec 17 18:31:02 1998 --- src/lib/libc/gen/getpwent.c Thu Jun 3 16:28:13 1999 *************** *** 255,260 **** --- 255,261 ---- _ypcache = (DB *)NULL; _yp_exclusions = 0; } + _yp_enabled = -1; #endif } >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message