Subject: lib/12389: kvm_doargv2() causes core dump if there is process with args longer than 'nchr'
To: None <gnats-bugs@gnats.netbsd.org>
From: Jaromír <jdolecek@NetBSD.org>
List: netbsd-bugs
Date: 03/12/2001 16:33:57
>Number:         12389
>Category:       lib
>Synopsis:       kvm_doargv2() causes core dump if there is process with args longer than 'nchr'
>Confidential:   no
>Severity:       serious
>Priority:       high
>Responsible:    lib-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Mon Mar 12 07:34:01 PST 2001
>Closed-Date:
>Last-Modified:
>Originator:     Jaromír Dolecek
>Release:        20010312
>Organization:
>Environment:
	
System: NetBSD saruman.ics.muni.cz 1.5S NetBSD 1.5S (SARUMAN) #30: Sun Mar 11 10:00:31 CET 2001 dolecek@saruman.ics.muni.cz:/usr/home/dolecek/soft/netbsd/sys/arch/i386/compile/SARUMAN i386
Architecture: i386
Machine: i386
>Description:
	Apparently, if the process arguments would exceed the space
	supplied by the sysctl caller, kernel doesn't terminate the
	string with '\0'. However, kvm_doargv2() doesn't handle
	this condition and doesn't ensure the string is terminated
	before using strlen(), leading to SIGSEGV commonly.

	Also, it seems like 'ap' should be reinitialized
	in the while() cycle if kd->argv is reallocated. This doesn't
	seem to have any effect though, seems likely the
	condition is never true currently.
>How-To-Repeat:
	> sh -c "sleep 100; echo /etc/ppp/ip-up ppp0 /dev/tty01 xxx.xxx.xxx.xxx /etc/ppp/ip-up ppp0 /dev/tty01 xxx.xxx.xxx.xxx" &
	> ps ax
>Fix:

Index: kvm_proc.c
===================================================================
RCS file: /cvsroot/basesrc/lib/libkvm/kvm_proc.c,v
retrieving revision 1.43
diff -u -p -u -r1.43 kvm_proc.c
--- kvm_proc.c	2000/12/22 23:11:19	1.43
+++ kvm_proc.c	2001/03/12 15:16:09
@@ -1073,6 +1073,7 @@ kvm_doargv2(kd, pid, type, nchr)
 	ap = kd->argv;
 	endp = bp + MIN(nchr, bufs);
 
+	bp[kd->arglen-1] = '\0';
 	while (bp < endp) {
 		*ap++ = bp;
 		/* XXX: don't need following anymore, or stick check for max argc in above while loop? */
@@ -1080,6 +1081,7 @@ kvm_doargv2(kd, pid, type, nchr)
 			kd->argc *= 2;
 			kd->argv = _kvm_realloc(kd, kd->argv,
 			    kd->argc * sizeof(*kd->argv));
+			ap = kd->argv;
 		}
 		bp += strlen(bp) + 1;
 	}
>Release-Note:
>Audit-Trail:
>Unformatted: