Re: fold -b1 segmentation fault

2010-10-22 Thread Bret S. Lambert
On Thu, Oct 21, 2010 at 05:57:24PM +0100, Jason McIntyre wrote:
 in case anyone's interested, and as reported in a recent freebsd pr:
 
   $ fold -b1
   Segmentation fault (core dumped)
 
 no fix is provided.
 
 jmc
 
 Number: 151592
 Category:   misc
 Synopsis:   'fold' segfaults on argument processing
 Confidential:   no
 Severity:   non-critical
 Priority:   low
 Responsible:freebsd-bugs
 State:  open
 Quarter:
 Keywords:   
 Date-Required:
 Class:  sw-bug
 Submitter-Id:   current-users
 Arrival-Date:   Wed Oct 20 03:50:08 UTC 2010
 Closed-Date:
 Last-Modified:
 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
 r...@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:
 Unformatted:
 

Fix appears to be to let getopt handle it, since allowing 0-9 as an
argument is not documented:


Index: fold.c
===
RCS file: /cvs/src/usr.bin/fold/fold.c,v
retrieving revision 1.12
diff -u -p -r1.12 fold.c
--- fold.c  27 Oct 2009 23:59:38 -  1.12
+++ fold.c  21 Oct 2010 17:26:24 -
@@ -57,7 +57,7 @@ main(int argc, char *argv[])
const char *errstr;
 
width = -1;
-   while ((ch = getopt(argc, argv, 0123456789bsw:)) != -1)
+   while ((ch = getopt(argc, argv, bsw:)) != -1)
switch (ch) {
case 'b':
count_bytes = 1;
@@ -70,21 +70,6 @@ main(int argc, char *argv[])
if (errstr != NULL)
errx(1, illegal width value, %s: %s, errstr, 
optarg);
-   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])
-   w = ++p;
-   else
-   w = argv[optind] + 1;
-
-   width = strtonum(w, 1, INT_MAX, errstr);
-   if (errstr != NULL)
-   errx(1, illegal width value, %s: %s, 
-   errstr, optarg);
-   }
break;
default:
(void)fprintf(stderr,



Re: fold -b1 segmentation fault

2010-10-21 Thread Chris Palmer
 Fix:
 I don't really see what the author is intending to do in that case
 statement where it breaks.

Agreed. Handing arguments for -w is properly done in the 'w' case with
optarg. Commenting out the digit cases gives the desired result:

strawberry:/usr/src/usr.bin/fold ; ./fold -b1
usage: fold [-bs] [-w width] [file ...]

You'd want to test further, but it seems like you could just delete those
digit cases and that they are dead, broken code.


-- 
http://noncombatant.org/



Re: fold -b1 segmentation fault

2010-10-21 Thread Matthias Kilian
On Thu, Oct 21, 2010 at 05:57:24PM +0100, Jason McIntyre wrote:
 in case anyone's interested, and as reported in a recent freebsd pr:
 
   $ fold -b1
   Segmentation fault (core dumped)
 
 no fix is provided.

Holy ugliness...

Here are two diffs, pick your choice.

Either drop the (attempt) to implemented obsolete syntax
(like `fold -42') completely:


Index: fold.c
===
RCS file: /cvs/src/usr.bin/fold/fold.c,v
retrieving revision 1.12
diff -u -p -r1.12 fold.c
--- fold.c  27 Oct 2009 23:59:38 -  1.12
+++ fold.c  21 Oct 2010 18:49:08 -
@@ -52,12 +52,10 @@ main(int argc, char *argv[])
 {
int ch;
int width;
-   char *p;
-   char *w;
const char *errstr;
 
-   width = -1;
-   while ((ch = getopt(argc, argv, 0123456789bsw:)) != -1)
+   width = DEFLINEWIDTH;
+   while ((ch = getopt(argc, argv, bsw:)) != -1)
switch (ch) {
case 'b':
count_bytes = 1;
@@ -71,21 +69,6 @@ main(int argc, char *argv[])
errx(1, illegal width value, %s: %s, errstr, 
optarg);
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])
-   w = ++p;
-   else
-   w = argv[optind] + 1;
-
-   width = strtonum(w, 1, INT_MAX, errstr);
-   if (errstr != NULL)
-   errx(1, illegal width value, %s: %s, 
-   errstr, optarg);
-   }
-   break;
default:
(void)fprintf(stderr,
usage: fold [-bs] [-w width] [file ...]\n);
@@ -93,9 +76,6 @@ main(int argc, char *argv[])
}
argv += optind;
argc -= optind;
-
-   if (width == -1)
-   width = DEFLINEWIDTH;
 
if (!*argv)
fold(width);


Or as an alternative keep the obsolete syntax but do not segfault
if it's mixed with normal options (like -b1 or -s1):


Index: fold.c
===
RCS file: /cvs/src/usr.bin/fold/fold.c,v
retrieving revision 1.12
diff -u -p -r1.12 fold.c
--- fold.c  27 Oct 2009 23:59:38 -  1.12
+++ fold.c  21 Oct 2010 18:47:40 -
@@ -53,7 +53,6 @@ main(int argc, char *argv[])
int ch;
int width;
char *p;
-   char *w;
const char *errstr;
 
width = -1;
@@ -75,12 +74,14 @@ main(int argc, char *argv[])
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])
-   w = ++p;
-   else
-   w = argv[optind] + 1;
-
-   width = strtonum(w, 1, INT_MAX, errstr);
+   if (p[0] != '-' || p[1] != ch || p[2])
+   p = argv[optind];
+   if (p == NULL || p[0] != '-' || p[1] != ch) {
+   (void)fprintf(stderr,
+   usage: fold [-bs] [-w width] [file 
...]\n);
+   exit(1);
+   }
+   width = strtonum(p + 1, 1, INT_MAX, errstr);
if (errstr != NULL)
errx(1, illegal width value, %s: %s, 
errstr, optarg);


Ciao,
Kili