Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 3 Jun 1999 17:44:04 +0300 (EEST)
From:      netch@lucky.net (Valentin Nechayev)
To:        FreeBSD-gnats-submit@freebsd.org
Subject:   bin/12008: getpwent() YP bug
Message-ID:  <199906031444.RAA84607@sivka.carrier.kiev.ua>

next in thread | raw e-mail | index | archive | help

>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 <stdio.h>
#include <stddef.h>
#include <pwd.h>

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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?199906031444.RAA84607>