From marcolz@stack.nl  Wed Jun 21 13:30:57 2000
Return-Path: <marcolz@stack.nl>
Received: from mailhost.stack.nl (vaak.stack.nl [131.155.140.140])
	by hub.freebsd.org (Postfix) with ESMTP id 3C40837B65D
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 21 Jun 2000 13:30:49 -0700 (PDT)
	(envelope-from marcolz@stack.nl)
Received: from toad.stack.nl (toad.stack.nl [131.155.140.135])
	by mailhost.stack.nl (Postfix) with ESMTP id 74A63156BC
	for <FreeBSD-gnats-submit@freebsd.org>; Wed, 21 Jun 2000 22:30:24 +0200 (CEST)
Received: by toad.stack.nl (Postfix, from userid 333)
	id F0882972A; Wed, 21 Jun 2000 22:30:23 +0200 (CEST)
Message-Id: <20000621203023.F0882972A@toad.stack.nl>
Date: Wed, 21 Jun 2000 22:30:23 +0200 (CEST)
From: marcolz@stack.nl
Reply-To: marcolz@stack.nl
To: FreeBSD-gnats-submit@freebsd.org
Subject: buffer overflow in ps
X-Send-Pr-Version: 3.2

>Number:         19422
>Category:       bin
>Synopsis:       users can overflow argv to make ps segfault
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    mikeh
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Jun 21 13:40:01 PDT 2000
>Closed-Date:    Mon Mar 18 11:34:51 PST 2002
>Last-Modified:  Mon Mar 18 11:34:51 PST 2002
>Originator:     Marc Olzheim
>Release:        FreeBSD 3.4-RELEASE i386
>Organization:
M.C.G.V. Stack
>Environment:

Doesn't matter.

>Description:

When a user reset his argv[0] within a program to a string, with a size larger
than sysconf(_SC_ARG_MAX), ps does not prevent it from overflowing an internal
buffer with strvis.

>How-To-Repeat:

A program that does argv[0] = blah; , where blah is a string, longer than
sysconf(_SC_ARG_MAX), and keeps waiting. Then just run 'ps wwwaxuU <user>'
and chances are ps segfaults.

>Fix:
	
--- /usr/src/bin/ps/fmt.c	Sat Aug 28 01:14:51 1999
+++ /usr/src/bin/ps/fmt.c	Wed Jun 21 22:19:22 2000
@@ -80,7 +80,7 @@
 	for (p = argv; (src = *p++) != 0; ) {
 		if (*src == 0)
 			continue;
-		strvis(dst, src, VIS_NL | VIS_CSTYLE);
+		strvisx(dst, src, arg_max - strlen(buf) - 1, VIS_NL | VIS_CSTYLE);
 		while (*dst)
 			dst++;
 		*dst++ = ' ';

>Release-Note:
>Audit-Trail:

From: Marc Olzheim <marcolz@stack.nl>
To: freebsd-gnats-submit@FreeBSD.org, marcolz@stack.nl
Cc:  
Subject: Re: bin/19422: users can overflow argv to make ps segfault
Date: Thu, 22 Jun 2000 16:58:12 +0200

 I must've been sleeping...
 A better patch would be:
 
 strvisx(dst, src, arg_max - (dst - buf) - 1, VIS_NL | VIS_CSTYLE);
 
 Btw. This is also the case with FreeBSD 4.0.
 
 Marc
 
State-Changed-From-To: open->feedback 
State-Changed-By: dd 
State-Changed-When: Wed Jun 27 18:39:20 PDT 2001 
State-Changed-Why:  
I can't reproduce this on a recent -current or -stable.  Is this still 
a problem? 


Responsible-Changed-From-To: freebsd-bugs->dd 
Responsible-Changed-By: dd 
Responsible-Changed-When: Wed Jun 27 18:39:20 PDT 2001 
Responsible-Changed-Why:  
My reminder to deal with this. 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=19422 

From: Mike Heffner <mheffner@novacoxmail.com>
To: dd@FreeBSD.org
Cc: freebsd-bugs@FreeBSD.org, marcolz@stack.nl,
	freebsd-gnats-submit@freebsd.org
Subject: Re: bin/19422: users can overflow argv to make ps segfault
Date: Thu, 28 Jun 2001 00:22:11 -0400 (EDT)

 When I looked at this it appears that rev. 1.10 of fmt.c was meant to fix this.
 However it looks like the change just increased the buffer size, but didn't
 put any restrictions on the strvis() -- which just means a bigger string is
 needed to overflow `buf'. But I haven't looked at the code in detail, so
 there might be caps on the size of argv[0] some where else that would block any
 overflow.
 
 
 On 28-Jun-2001 dd@FreeBSD.org wrote:
 | Synopsis: users can overflow argv to make ps segfault
 | 
 | State-Changed-From-To: open->feedback
 | State-Changed-By: dd
 | State-Changed-When: Wed Jun 27 18:39:20 PDT 2001
 | State-Changed-Why: 
 | I can't reproduce this on a recent -current or -stable.  Is this still
 | a problem?
 
 
 Mike
 
 -- 
   Mike Heffner         <mheffner@[acm.]vt.edu>
   Fredericksburg, VA       <mikeh@FreeBSD.org>
 

From: Marc Olzheim <marcolz@ilse.nl>
To: freebsd-gnats-submit@FreeBSD.org, marcolz@stack.nl
Cc:  
Subject: Re: bin/19422: users can overflow argv to make ps segfault
Date: Thu, 28 Jun 2001 13:58:28 +0200

 It's still possible:
 
 #include	<stdio.h>
 #include	<sys/exec.h>
 #include	<sys/param.h>
 #include	<sys/sysctl.h>
 #include	<sys/types.h>
 #include	<unistd.h>
 
 int
 main(int argc, char *argv[])
 {
 	int	oid[4];
 	char	buf[65537];
 
 	if (argc >= 2)
 		argv[0] = argv[1];
 	else
 	{
 		memset(buf, 'A', 65537);
 		argv[0] = buf;
 	}
 
 	// setproctitle("%s", argv[0]);
 
 	oid[0] = CTL_KERN;
 	oid[1] = KERN_PROC;
 	oid[2] = KERN_PROC_ARGS;
 	oid[3] = getpid();
 	sysctl(oid, 4, 0, 0, buf, 65537);
 
 	sleep(600);
 
 	return(0);
 }
 
 Run it and do a ps uxwww
 ps either segfaults or shows you some strvis-d data.
 
 Marc

From: Marc Olzheim <marcolz@stack.nl>
To: Marc Olzheim <marcolz@ilse.nl>
Cc: freebsd-gnats-submit@FreeBSD.org, marcolz@stack.nl
Subject: Re: bin/19422: users can overflow argv to make ps segfault
Date: Thu, 28 Jun 2001 14:03:27 +0200

 And if you put a
 #if __FreeBSD__ == 4
 and a #endif around the setproctitle stuff, it will run on both
 FreeBSD 3 and 4
 
 Marc

From: Marc Olzheim <marcolz@ilse.nl>
To: freebsd-gnats-submit@FreeBSD.org, marcolz@stack.nl
Cc:  
Subject: Re: bin/19422: users can overflow argv to make ps segfault
Date: Sat, 1 Sep 2001 17:03:20 +0200

 FreeBSD 5.0 still has the same problem...
 
 Marc
Responsible-Changed-From-To: dd->freebsd-bugs 
Responsible-Changed-By: dd 
Responsible-Changed-When: Sat Nov 24 08:30:51 PST 2001 
Responsible-Changed-Why:  
I still can't reproduce this with the originator's code, and don't have time 
to persure this further. 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=19422 
Responsible-Changed-From-To: freebsd-bugs->mikeh 
Responsible-Changed-By: mikeh 
Responsible-Changed-When: Mon Nov 26 20:37:01 PST 2001 
Responsible-Changed-Why:  
I'll look at this  in the next couple weeks. 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=19422 

From: Mike Heffner <mheffner@vt.edu>
To: freebsd-gnats-submit@freebsd.org
Cc: Marc Olzheim <marcolz@ilse.nl>,
	FreeBSD-bugs <freebsd-bugs@freebsd.org>
Subject: Re: bin/19422: users can overflow argv to make ps segfault
Date: Tue, 11 Dec 2001 23:18:54 -0500 (EST)

 This message is in MIME format
 --_=XFMail.1.5.2.FreeBSD:20011211231854:24503=_
 Content-Type: text/plain; charset=us-ascii
 
 
 Well, I've looked at this a little more. I was able to reproduce it (it
 took a few times though). Unfortunately, the patch isn't as simple as the
 one in the PR. Could you please try the attached patch? There is still a
 problem though, and that is that the strlen()s can seg. fault if the
 argv[] strings aren't NULL terminated - I don't know how to fix this
 problem though :(
 
 Mike
 
 -- 
   Mike Heffner     <mheffner@[acm.]vt.edu>
   Blacksburg, VA       <mikeh@FreeBSD.org>
 
 
 --_=XFMail.1.5.2.FreeBSD:20011211231854:24503=_
 Content-Disposition: attachment; filename="ps.argoflow.diff"
 Content-Transfer-Encoding: 7bit
 Content-Description: ps.argoflow.diff
 Content-Type: text/plain;
  charset=us-ascii; name=ps.argoflow.diff; SizeOnDisk=908
 
 Index: fmt.c
 ===================================================================
 RCS file: /home/ncvs/src/bin/ps/fmt.c,v
 retrieving revision 1.14
 diff -u -r1.14 fmt.c
 --- fmt.c	27 Aug 1999 23:14:51 -0000	1.14
 +++ fmt.c	12 Dec 2001 04:12:24 -0000
 @@ -61,7 +61,8 @@
  shquote(argv)
  	char **argv;
  {
 -	long arg_max;
 +	static long arg_max = -1;
 +	long len;
  	char **p, *dst, *src;
  	static char *buf = NULL;
  
 @@ -80,13 +81,16 @@
  	for (p = argv; (src = *p++) != 0; ) {
  		if (*src == 0)
  			continue;
 -		strvis(dst, src, VIS_NL | VIS_CSTYLE);
 +		len = (4 * arg_max - (dst - buf)) / 4;
 +		strvisx(dst, src, strlen(src) < len ? strlen(src) : len,
 +		    VIS_NL | VIS_CSTYLE);
  		while (*dst)
  			dst++;
 -		*dst++ = ' ';
 +		if ((4 * arg_max - (dst - buf)) / 4 > 0)
 +			*dst++ = ' ';
  	}
  	/* Chop off trailing space */
 -	if (dst != buf)
 +	if (dst != buf && dst[-1] == ' ')
  		dst--;
  	*dst = '\0';
  	return (buf);
 
 --_=XFMail.1.5.2.FreeBSD:20011211231854:24503=_--
 End of MIME message

From: Peter Pentchev <roam@ringlet.net>
To: Mike Heffner <mheffner@vt.edu>
Cc: freebsd-gnats-submit@freebsd.org, Marc Olzheim <marcolz@ilse.nl>,
	FreeBSD-bugs <freebsd-bugs@freebsd.org>
Subject: Re: bin/19422: users can overflow argv to make ps segfault
Date: Wed, 12 Dec 2001 11:50:39 +0200

 On Tue, Dec 11, 2001 at 11:18:54PM -0500, Mike Heffner wrote:
 > 
 > Well, I've looked at this a little more. I was able to reproduce it (it
 > took a few times though). Unfortunately, the patch isn't as simple as the
 > one in the PR. Could you please try the attached patch? There is still a
 > problem though, and that is that the strlen()s can seg. fault if the
 > argv[] strings aren't NULL terminated - I don't know how to fix this
 > problem though :(
 
 If argv[] is the program arguments' array, as passed to main(), then
 you should not worry about it - its elements are supposed to be proper
 C strings, i.e. terminated by a '\0' character, and I still have to see
 a platform where they are not :)
 
 G'luck,
 Peter
 
 -- 
 This sentence would be seven words long if it were six words shorter.

From: Mike Heffner <mheffner@vt.edu>
To: Peter Pentchev <roam@ringlet.net>
Cc: FreeBSD-bugs <freebsd-bugs@freebsd.org>,
	Marc Olzheim <marcolz@ilse.nl>, freebsd-gnats-submit@freebsd.org
Subject: Re: bin/19422: users can overflow argv to make ps segfault
Date: Wed, 12 Dec 2001 10:36:03 -0500 (EST)

 This message is in MIME format
 --_=XFMail.1.5.2.FreeBSD:20011212103603:24503=_
 Content-Type: text/plain; charset=us-ascii
 
 
 On 12-Dec-2001 Peter Pentchev wrote:
 | On Tue, Dec 11, 2001 at 11:18:54PM -0500, Mike Heffner wrote:
 |> 
 |> Well, I've looked at this a little more. I was able to reproduce it (it
 |> took a few times though). Unfortunately, the patch isn't as simple as
 |> the
 |> one in the PR. Could you please try the attached patch? There is still
 |> a
 |> problem though, and that is that the strlen()s can seg. fault if the
 |> argv[] strings aren't NULL terminated - I don't know how to fix this
 |> problem though :(
 | 
 | If argv[] is the program arguments' array, as passed to main(), then
 | you should not worry about it - its elements are supposed to be proper
 | C strings, i.e. terminated by a '\0' character, and I still have to see
 | a platform where they are not :)
 
 
 But when a user modifies those arguments by explicilty setting argv[0], or
 whatever, is where the problem is:
 
 test5.c:
 
 #include       <stdio.h>
 #include       <sys/exec.h>
 #include       <sys/param.h>
 #include       <sys/sysctl.h>
 #include       <sys/types.h>
 #include       <unistd.h>
 
 int
 main(int argc, char *argv[])
 {
         int     oid[4];
         char    before[] = "BBBBBBB";
         char    after[5];
 
         memset(after, 'A', sizeof(after));
         argv[0] = after;
       
         oid[0] = CTL_KERN;
         oid[1] = KERN_PROC;
         oid[2] = KERN_PROC_ARGS;
         oid[3] = getpid();
         sysctl(oid, 4, 0, 0, after, 65537);
       
         sleep(600);
       
         return(0);
 }
 
 
 $ ./test5
 
 
 on another terminal:
 
 $ ps auxwww
 
 ...
 spock   290  0.0  0.3   980  109  p0  S+   10:30AM   0:00.01 \
 AAAAA\M-{\M-?\M-?BBBBBBB (test5)
      ^^^^^^^^^^^^^^^^^^^
 
 
 
 Mike
 
 -- 
   Mike Heffner     <mheffner@[acm.]vt.edu>
   Blacksburg, VA       <mikeh@FreeBSD.org>
 
 
 --_=XFMail.1.5.2.FreeBSD:20011212103603:24503=_
 Content-Type: application/pgp-signature
 
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.0.6 (FreeBSD)
 Comment: For info see http://www.gnupg.org
 
 iD8DBQE8F3liFokZQs3sv5kRAiVSAKCTfdqsGylIHlKsVUh+p5mcmRX/rACeOrCC
 aOsuNDWHNxu0Z6XjBrRHc/4=
 =RGXk
 -----END PGP SIGNATURE-----
 
 --_=XFMail.1.5.2.FreeBSD:20011212103603:24503=_--
 End of MIME message
State-Changed-From-To: feedback->analyzed 
State-Changed-By: mikeh 
State-Changed-When: Mon Jan 21 11:40:29 PST 2002 
State-Changed-Why:  
Fix committed to current, awaiting MFC. 

http://www.FreeBSD.org/cgi/query-pr.cgi?pr=19422 
State-Changed-From-To: analyzed->closed 
State-Changed-By: mikeh 
State-Changed-When: Mon Mar 18 11:34:13 PST 2002 
State-Changed-Why:  
Fix MFC'd. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=19422 
>Unformatted:
