Re: fold -b1 segmentation fault
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
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
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