Subject: lib/3580: bugs in the getpwent.c
To: None <gnats-bugs@gnats.netbsd.org>
From: None <msaitoh@spa.is.uec.ac.jp>
List: netbsd-bugs
Date: 05/06/1997 13:38:22
>Number:         3580
>Category:       lib
>Synopsis:       bugs in the getpwent.c
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    lib-bug-people (Library Bug People)
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue May  6 06:50:01 1997
>Last-Modified:
>Originator:     SAITOH Masanobu
>Organization:
>Release:        latest -current
>Environment:
System: NetBSD ifree.spa.is.uec.ac.jp 1.2D NetBSD 1.2D (IFREE) #41: Sat May 3 19:13:19 JST 1997 msaitoh@ifree.spa.is.uec.ac.jp:/var/sources/src/sys/arch/i386/compile/IFREE i386


>Description:
	On my system, "finger xxx yyy" dumps core.

	It neeeds the dummy (non-existent user's) YP entry in the password
	file to dumps core (so that the yp_match() make an error).

------------------------ gdb log  ------------------------
Script started on Fri May  2 12:56:56 1997
ifree(msaitoh)% ./finger xxx yyy
Bus error (core dumped)
ifree(msaitoh)% gdb finger finger.core
GDB is free software and you are welcome to distribute copies of it
 under certain conditions; type "show copying" to see the conditions.
There is absolutely no warranty for GDB; type "show warranty" for details.
GDB 4.11 (i386-netbsd), Copyright 1993 Free Software Foundation, Inc...
Core was generated by `finger'.
Program terminated with signal 10, Bus error.
Reading symbols from /usr/libexec/ld.so...done.
Reading symbols from /usr/lib/libc.so.12.14...done.
#0  0x400659ac in free ()
(gdb) where
#0  0x400659ac in free ()
#1  0x3ce0 in getpwent () at getpwent.c:362
#2  0x1c45 in userlist (argc=2, argv=0xf7bfd604) at finger.c:230
#3  0x19df in main (argc=2, argv=0xf7bfd604) at finger.c:140
(gdb) up
#1  0x3ce0 in getpwent () at getpwent.c:362
362                                                     free(data);
(gdb) list
357                                     __ypmode = YPMODE_NONE;
358                                     free(name);
359                                     name = (char *)NULL;
360                                     if(r != 0) {
361                                             if(data)
362                                                     free(data); <== here
363                                             goto again;
364                                     }
365                                     bcopy(data, line, datalen);
366                                     free(data);
(gdb) print data
$1 = 0x1 ""		<================== garbage
(gdb) list getpwent
258     }
259     #endif
260     
261     struct passwd *
262     getpwent()
263     {
264             DBT key;
265             char bf[sizeof(_pw_keynum) + 1];
266     #ifdef YP
267             char *cp;
(gdb) 
268             static char *name = (char *)NULL;
269             const char *user, *host, *dom;
270             int has_yppw;
271     #endif
272     
273             if (!_pw_db && !__initdb())
274                     return((struct passwd *)NULL);
275     
276     #ifdef YP
277             has_yppw = __has_yppw();
(gdb) 
278     
279     again:
280             if(has_yppw && (__ypmode != YPMODE_NONE)) {
281                     char *key, *data;
282                     int keylen, datalen;
283                     int r, s;
284     
285                     if(!__ypdomain) {
286                             if( _yp_check(&__ypdomain) == 0) {
287                                     __ypmode = YPMODE_NONE;
(gdb) break 285
Breakpoint 1 at 0x3ac3: file getpwent.c, line 285.
(gdb) run xxx yyy
Starting program: /var/sources/src/usr.bin/finger/finger xxx yyy

Breakpoint 1, getpwent () at getpwent.c:285
285                     if(!__ypdomain) {
(gdb) print data
$2 = 0x1 ""		<==== garbage (first time!)
(gdb) list 352
347                             }
348                             bcopy(data, line, datalen);
349                             free(data);
350                             data = (char *)NULL;
351                             break;
352                     case YPMODE_USER:
353                             if(name != (char *)NULL) {
354                                     r = yp_match(__ypdomain, "passwd.byname",
355                                             name, strlen(name),
356                                             &data, &datalen);
(gdb) 
357                                     __ypmode = YPMODE_NONE;
358                                     free(name);
359                                     name = (char *)NULL;
360                                     if(r != 0) {
361                                             if(data)
362                                                     free(data);
363                                             goto again;
364                                     }
365                                     bcopy(data, line, datalen);
366                                     free(data);
(gdb) break 353
Breakpoint 2 at 0x3c68: file getpwent.c, line 353.
(gdb) delete 1
(gdb) cont
Continuing.

Breakpoint 2, getpwent () at getpwent.c:353
353                             if(name != (char *)NULL) {
(gdb) step
354                                     r = yp_match(__ypdomain, "passwd.byname",
(gdb) 
357                                     __ypmode = YPMODE_NONE;
(gdb) 
358                                     free(name);
(gdb) 
359                                     name = (char *)NULL;
(gdb) 
360                                     if(r != 0) {
(gdb) 
361                                             if(data)
(gdb) 
362                                                     free(data);
(gdb) print data
$3 = 0x1 ""		<==== garbage
(gdb) step

Program received signal SIGBUS (10), Bus error
0x400659ac in free ()
(gdb) quit
--------------------------------- end -------------------------------


>How-To-Repeat:
	finger xxx yyy
	This may not occur on your system.
>Fix:
	Reset "char *data" with NULL in the getpwent() first.
>Audit-Trail:
>Unformatted: