Subject: bin/36820: ypserv maplist functionality broken due to off-by-one error
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: None <gcw@primenet.com.au>
List: netbsd-bugs
Date: 08/22/2007 03:05:01
>Number:         36820
>Category:       bin
>Synopsis:       ypserv maplist functionality broken due to off-by-one error
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Wed Aug 22 03:05:01 +0000 2007
>Originator:     Geoff C. Wing
>Release:        NetBSD 4.99.29 (since 20 May 2006)
>Organization:
>Environment:
System: NetBSD g.primenet.com.au 4.99.29 NetBSD 4.99.29 (G) #0: Mon Aug 20 13:52:27 EST 2007 gcw@g.primenet.com.au:/usr/netbsd/src/sys/arch/i386/compile/G i386
Architecture: i386
Machine: i386
>Description:
	A change in ypproc_maplist_2_svc() in ypserv to use strlcpy() uses
	a length one short of the desired length (it doesn't include the NUL
	character when considering length) so maplist entries returned are all
	one character short.

	Previously it did a 
		strncpy(dst, src, d_namlen - 3)
		dst[d_namlen - 3] = '\0'
	Now it does
		strlcpy(dst, src, d_namlen - 3)

	Also, there's a trivial string overflow to avoid if a file created in
	the map directory is greater than YPMAXMAP + 3 chars long and ends in
	".db", i.e. > 67 chars long.  Maps longer than that should be dropped
	since they can't be pushed.

>How-To-Repeat:
	Set up YP/NIS.

	% ypwhich -m -f mynis.
	ypwhich: clnt_call: mynis.: netid.bynam: No such map in server's domain
	ypwhich: clnt_call: mynis.: protocols.bynam: No such map in server's domain
	ypwhich: clnt_call: mynis.: protocols.bynumbe: No such map in server's domain
	ypwhich: clnt_call: mynis.: services.bynam: No such map in server's domain
	...

>Fix:
	
Index: usr.sbin/ypserv/ypserv/ypserv_proc.c
===================================================================
RCS file: /cvsroot/src/usr.sbin/ypserv/ypserv/ypserv_proc.c,v
retrieving revision 1.11
diff -u -p -r1.11 ypserv_proc.c
--- usr.sbin/ypserv/ypserv/ypserv_proc.c	20 May 2006 20:03:28 -0000	1.11
+++ usr.sbin/ypserv/ypserv/ypserv_proc.c	22 Aug 2007 02:54:51 -0000
@@ -474,7 +474,7 @@ ypproc_maplist_2_svc(void *argp, struct 
 		/* Eliminate impossible names. */
 		if ((strcmp(dp->d_name, ".") == 0) ||
 		    ((strcmp(dp->d_name, "..") == 0)) ||
-		    (dp->d_namlen < 4))
+		    (dp->d_namlen < 4) || (dp->d_namlen > YPMAXMAP + 3))
 			continue;
 
 		/* Check the file suffix. */
@@ -490,7 +490,7 @@ ypproc_maplist_2_svc(void *argp, struct 
 
 			(void)memset(m, 0, sizeof(m));
 			(void)strlcpy(m->ypml_name, dp->d_name,
-			    (size_t)(dp->d_namlen - 3));
+			    (size_t)(dp->d_namlen - 2));
 			m->ypml_next = res.list;
 			res.list = m;
 		}