From nobody@FreeBSD.org  Wed Oct 20 03:43:27 2010
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id 9417C106566B
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 20 Oct 2010 03:43:27 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id 8310A8FC16
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 20 Oct 2010 03:43:27 +0000 (UTC)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.3/8.14.3) with ESMTP id o9K3hR2w035876
	for <freebsd-gnats-submit@FreeBSD.org>; Wed, 20 Oct 2010 03:43:27 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.3/8.14.3/Submit) id o9K3hR0P035875;
	Wed, 20 Oct 2010 03:43:27 GMT
	(envelope-from nobody)
Message-Id: <201010200343.o9K3hR0P035875@www.freebsd.org>
Date: Wed, 20 Oct 2010 03:43:27 GMT
From: Marcus Reid <marcus@blazingdot.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: 'fold' segfaults on argument processing
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         151592
>Category:       bin
>Synopsis:       fold(1) segfaults on argument processing
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Wed Oct 20 03:50:08 UTC 2010
>Closed-Date:    Tue Nov 09 21:08:51 UTC 2010
>Last-Modified:  Tue Nov 09 21:08:51 UTC 2010
>Originator:     Marcus Reid
>Release:        8.1-STABLE
>Organization:
>Environment:
FreeBSD austin.sea.netifice.com 8.1-STABLE FreeBSD 8.1-STABLE #0: Mon Sep 20 23:53:47 PDT 2010     root@austin.sea.netifice.com:/usr/obj/usr/src/sys/FARK  amd64
>Description:
The 'fold' utility reads past the end of a buffer if arguments are incorrectly specified.  If you pass an argument to '-b' that happens to be in the character set "0123456789", line 101 reads past the end of argv[optind] and causes a segmentation fault.
>How-To-Repeat:
Simply run 'fold -b1'
>Fix:
I don't really see what the author is intending to do in that case statement where it breaks.

>Release-Note:
>Audit-Trail:

From: =?ISO-8859-1?Q?Jean-S=E9bastien_P=E9dron?=
 <jean-sebastien.pedron@dumbbell.fr>
To: bug-followup@FreeBSD.org, marcus@blazingdot.com
Cc:  
Subject: Re: bin/151592: fold(1) segfaults on argument processing
Date: Wed, 03 Nov 2010 23:05:32 +0100

 This is a multi-part message in MIME format.
 --------------060509040604060902020702
 Content-Type: text/plain; charset=ISO-8859-1
 Content-Transfer-Encoding: 8bit
 
 Hello!
 
 Attached is a patch that fixes the segfault for me. Could you please try
 it with your use case?
 
 How to apply the patch:
   # cd /usr/src
   # patch < /path/to/fold-segfault-a.patch
   # cd usr.bin/fold
   # make
 
 You will find a new "fold" binary in this directory or in
 /usr/obj/usr/src/usr.bin/fold if you have a buildworld still present.
 
 Thanks!
 
 -- 
 Jean-Sbastien Pdron
 
 --------------060509040604060902020702
 Content-Type: text/plain;
  name="fold-segfault-a.patch"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: attachment;
  filename="fold-segfault-a.patch"
 
 Index: usr.bin/fold/fold.c
 ===================================================================
 --- usr.bin/fold/fold.c	(revision 214762)
 +++ usr.bin/fold/fold.c	(working copy)
 @@ -71,14 +71,14 @@
  int
  main(int argc, char **argv)
  {
 -	int ch;
 +	int ch, previous_ch;
  	int rval, width;
 -	char *p;
  
  	(void) setlocale(LC_CTYPE, "");
  
  	width = -1;
 -	while ((ch = getopt(argc, argv, "0123456789bsw:")) != -1)
 +	previous_ch = 0;
 +	while ((ch = getopt(argc, argv, "0123456789bsw:")) != -1) {
  		switch (ch) {
  		case 'b':
  			bflag = 1;
 @@ -93,17 +93,33 @@
  			break;
  		case '0': case '1': case '2': case '3': case '4':
  		case '5': case '6': case '7': case '8': case '9':
 -			if (width == -1) {
 -				p = argv[optind - 1];
 -				if (p[0] == '-' && p[1] == ch && !p[2])
 -					width = atoi(++p);
 -				else
 -					width = atoi(argv[optind] + 1);
 +			/* Accept a width as eg. -30. Note that a width
 +			 * specified using the -w option is always used prior
 +			 * to this undocumented option. */
 +			switch (previous_ch) {
 +			case '0': case '1': case '2': case '3': case '4':
 +			case '5': case '6': case '7': case '8': case '9':
 +				/* The width is a number with multiple digits:
 +				 * add the last one. */
 +				width = width * 10 + (ch - '0');
 +				break;
 +			default:
 +				/* Set the width, unless it was previously
 +				 * set. For instance, the following options
 +				 * would all give a width of 5 and not 10:
 +				 *   -10 -w5
 +				 *   -5b10
 +				 *   -5 -10b */
 +				if (width == -1)
 +					width = ch - '0';
 +				break;
  			}
  			break;
  		default:
  			usage();
  		}
 +		previous_ch = ch;
 +	}
  	argv += optind;
  	argc -= optind;
  
 
 --------------060509040604060902020702--

From: Marcus Reid <marcus@blazingdot.com>
To: Jean-S?bastien P?dron <jean-sebastien.pedron@dumbbell.fr>
Cc: bug-followup@FreeBSD.org
Subject: Re: bin/151592: fold(1) segfaults on argument processing
Date: Wed, 3 Nov 2010 20:55:04 -0800

 On Wed, Nov 03, 2010 at 11:05:32PM +0100, Jean-S?bastien P?dron wrote:
 > Hello!
 > 
 > Attached is a patch that fixes the segfault for me. Could you please try
 > it with your use case?
 > 
 > How to apply the patch:
 >   # cd /usr/src
 >   # patch < /path/to/fold-segfault-a.patch
 >   # cd usr.bin/fold
 >   # make
 > 
 > You will find a new "fold" binary in this directory or in
 > /usr/obj/usr/src/usr.bin/fold if you have a buildworld still present.
 
 Works for me, and seems to make things more compatible with the
 GNU version as well.  Thanks for looking into this!
 
 Marcus

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/151592: commit references a PR
Date: Sat,  6 Nov 2010 17:48:52 +0000 (UTC)

 Author: dumbbell
 Date: Sat Nov  6 17:48:46 2010
 New Revision: 214893
 URL: http://svn.freebsd.org/changeset/base/214893
 
 Log:
   Fix a segmentation fault in argument processing.
   
   The crash was caused by a command line such as this one:
   # foldl -b1
   
   PR:		bin/151592
   Reported by:	Marcus Reid <marcus@blazingdot.com>
   Tested by:	Marcus Reid <marcus@blazingdot.com>
   MFC after:	3 days
 
 Modified:
   head/usr.bin/fold/fold.c
 
 Modified: head/usr.bin/fold/fold.c
 ==============================================================================
 --- head/usr.bin/fold/fold.c	Sat Nov  6 16:09:25 2010	(r214892)
 +++ head/usr.bin/fold/fold.c	Sat Nov  6 17:48:46 2010	(r214893)
 @@ -71,14 +71,14 @@ int sflag;			/* Split on word boundaries
  int
  main(int argc, char **argv)
  {
 -	int ch;
 +	int ch, previous_ch;
  	int rval, width;
 -	char *p;
  
  	(void) setlocale(LC_CTYPE, "");
  
  	width = -1;
 -	while ((ch = getopt(argc, argv, "0123456789bsw:")) != -1)
 +	previous_ch = 0;
 +	while ((ch = getopt(argc, argv, "0123456789bsw:")) != -1) {
  		switch (ch) {
  		case 'b':
  			bflag = 1;
 @@ -93,17 +93,33 @@ main(int argc, char **argv)
  			break;
  		case '0': case '1': case '2': case '3': case '4':
  		case '5': case '6': case '7': case '8': case '9':
 -			if (width == -1) {
 -				p = argv[optind - 1];
 -				if (p[0] == '-' && p[1] == ch && !p[2])
 -					width = atoi(++p);
 -				else
 -					width = atoi(argv[optind] + 1);
 +			/* Accept a width as eg. -30. Note that a width
 +			 * specified using the -w option is always used prior
 +			 * to this undocumented option. */
 +			switch (previous_ch) {
 +			case '0': case '1': case '2': case '3': case '4':
 +			case '5': case '6': case '7': case '8': case '9':
 +				/* The width is a number with multiple digits:
 +				 * add the last one. */
 +				width = width * 10 + (ch - '0');
 +				break;
 +			default:
 +				/* Set the width, unless it was previously
 +				 * set. For instance, the following options
 +				 * would all give a width of 5 and not 10:
 +				 *   -10 -w5
 +				 *   -5b10
 +				 *   -5 -10b */
 +				if (width == -1)
 +					width = ch - '0';
 +				break;
  			}
  			break;
  		default:
  			usage();
  		}
 +		previous_ch = ch;
 +	}
  	argv += optind;
  	argc -= optind;
  
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/151592: commit references a PR
Date: Tue,  9 Nov 2010 20:45:01 +0000 (UTC)

 Author: dumbbell
 Date: Tue Nov  9 20:44:55 2010
 New Revision: 215053
 URL: http://svn.freebsd.org/changeset/base/215053
 
 Log:
   MFC r214893:
   Fix a segmentation fault in argument processing.
   
   The crash was caused by a command line such as this one:
   # fold -b1
   
   PR:		bin/151592
   Reporter by:	Marcus Reid <marcus@blazingdot.com>
   Tested by:	Marcus Reid <marcus@blazingdot.com>
 
 Modified:
   stable/8/usr.bin/fold/fold.c
 Directory Properties:
   stable/8/usr.bin/fold/   (props changed)
 
 Modified: stable/8/usr.bin/fold/fold.c
 ==============================================================================
 --- stable/8/usr.bin/fold/fold.c	Tue Nov  9 20:41:10 2010	(r215052)
 +++ stable/8/usr.bin/fold/fold.c	Tue Nov  9 20:44:55 2010	(r215053)
 @@ -71,14 +71,14 @@ int sflag;			/* Split on word boundaries
  int
  main(int argc, char **argv)
  {
 -	int ch;
 +	int ch, previous_ch;
  	int rval, width;
 -	char *p;
  
  	(void) setlocale(LC_CTYPE, "");
  
  	width = -1;
 -	while ((ch = getopt(argc, argv, "0123456789bsw:")) != -1)
 +	previous_ch = 0;
 +	while ((ch = getopt(argc, argv, "0123456789bsw:")) != -1) {
  		switch (ch) {
  		case 'b':
  			bflag = 1;
 @@ -93,17 +93,33 @@ main(int argc, char **argv)
  			break;
  		case '0': case '1': case '2': case '3': case '4':
  		case '5': case '6': case '7': case '8': case '9':
 -			if (width == -1) {
 -				p = argv[optind - 1];
 -				if (p[0] == '-' && p[1] == ch && !p[2])
 -					width = atoi(++p);
 -				else
 -					width = atoi(argv[optind] + 1);
 +			/* Accept a width as eg. -30. Note that a width
 +			 * specified using the -w option is always used prior
 +			 * to this undocumented option. */
 +			switch (previous_ch) {
 +			case '0': case '1': case '2': case '3': case '4':
 +			case '5': case '6': case '7': case '8': case '9':
 +				/* The width is a number with multiple digits:
 +				 * add the last one. */
 +				width = width * 10 + (ch - '0');
 +				break;
 +			default:
 +				/* Set the width, unless it was previously
 +				 * set. For instance, the following options
 +				 * would all give a width of 5 and not 10:
 +				 *   -10 -w5
 +				 *   -5b10
 +				 *   -5 -10b */
 +				if (width == -1)
 +					width = ch - '0';
 +				break;
  			}
  			break;
  		default:
  			usage();
  		}
 +		previous_ch = ch;
 +	}
  	argv += optind;
  	argc -= optind;
  
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: bin/151592: commit references a PR
Date: Tue,  9 Nov 2010 20:57:01 +0000 (UTC)

 Author: dumbbell
 Date: Tue Nov  9 20:56:55 2010
 New Revision: 215055
 URL: http://svn.freebsd.org/changeset/base/215055
 
 Log:
   MFC r214893:
   Fix a segmentation fault in argument processing.
   
   The crash was caused by a command line such as this one:
   # fold -b1
   
   PR:		bin/151592
   Reported by:	Marcus Reid <marcus@blazingdot.com>
   Tested by:	Marcus Reid <marcus@blazingdot.com>
 
 Modified:
   stable/7/usr.bin/fold/fold.c
 Directory Properties:
   stable/7/usr.bin/fold/   (props changed)
 
 Modified: stable/7/usr.bin/fold/fold.c
 ==============================================================================
 --- stable/7/usr.bin/fold/fold.c	Tue Nov  9 20:46:41 2010	(r215054)
 +++ stable/7/usr.bin/fold/fold.c	Tue Nov  9 20:56:55 2010	(r215055)
 @@ -71,14 +71,14 @@ int sflag;			/* Split on word boundaries
  int
  main(int argc, char **argv)
  {
 -	int ch;
 +	int ch, previous_ch;
  	int rval, width;
 -	char *p;
  
  	(void) setlocale(LC_CTYPE, "");
  
  	width = -1;
 -	while ((ch = getopt(argc, argv, "0123456789bsw:")) != -1)
 +	previous_ch = 0;
 +	while ((ch = getopt(argc, argv, "0123456789bsw:")) != -1) {
  		switch (ch) {
  		case 'b':
  			bflag = 1;
 @@ -93,17 +93,33 @@ main(int argc, char **argv)
  			break;
  		case '0': case '1': case '2': case '3': case '4':
  		case '5': case '6': case '7': case '8': case '9':
 -			if (width == -1) {
 -				p = argv[optind - 1];
 -				if (p[0] == '-' && p[1] == ch && !p[2])
 -					width = atoi(++p);
 -				else
 -					width = atoi(argv[optind] + 1);
 +			/* Accept a width as eg. -30. Note that a width
 +			 * specified using the -w option is always used prior
 +			 * to this undocumented option. */
 +			switch (previous_ch) {
 +			case '0': case '1': case '2': case '3': case '4':
 +			case '5': case '6': case '7': case '8': case '9':
 +				/* The width is a number with multiple digits:
 +				 * add the last one. */
 +				width = width * 10 + (ch - '0');
 +				break;
 +			default:
 +				/* Set the width, unless it was previously
 +				 * set. For instance, the following options
 +				 * would all give a width of 5 and not 10:
 +				 *   -10 -w5
 +				 *   -5b10
 +				 *   -5 -10b */
 +				if (width == -1)
 +					width = ch - '0';
 +				break;
  			}
  			break;
  		default:
  			usage();
  		}
 +		previous_ch = ch;
 +	}
  	argv += optind;
  	argc -= optind;
  
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 
State-Changed-From-To: open->closed 
State-Changed-By: dumbbell 
State-Changed-When: Tue Nov 9 21:01:10 UTC 2010 
State-Changed-Why:  
Fix committed to HEAD and MFC'd to stable/8 and stable/7. 

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