Subject: bin/32322: Division by zero in column(1) with certain column widths
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: None <daniel@netbsd.org>
List: netbsd-bugs
Date: 12/17/2005 16:10:00
>Number: 32322
>Category: bin
>Synopsis: Division by zero in column(1) with certain column widths
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: bin-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sat Dec 17 16:10:00 +0000 2005
>Originator: Daniel de Kok
>Release: NetBSD 3.0RC6
>Organization:
>Environment:
NetBSD terrapin.taickim.net 3.0_RC6 NetBSD 3.0_RC6 (GENERIC) #0: Fri Dec 9 09:39:00 UTC 2005 riz@faith.netbsd.org:/home/builds/ab/netbsd-3-0-RC6/i386/200512090458Z-obj/home/builds/ab/netbsd-3-0-RC6/src/sys/arch/i386/compile/GENERIC i386
>Description:
column(1) core dumps when the column width is smaller than or equal to maxlength, because the rounding up of the line length is done after the safety checks, causing a division by zero. This also applies to -current.
Could someone with userland expertise review the attached patch?
>How-To-Repeat:
$ ls
GNUstep muziek netbsd source unixbook
$ ls | column -c 10
Floating point exception (core dumped)
#0 0x08048ee9 in r_columnate () at column.c:171
171 numrows = entries / numcols;
(gdb) bt full
#0 0x08048ee9 in r_columnate () at column.c:171
base = -1077941812
chcnt = 134523112
cnt = 134515936
col = -1077941912
endcol = -1077941812
numcols = 0
numrows = 8
row = -1077944056
#1 0x08048d9d in main (argc=0, argv=0xbfbfe9d8) at column.c:130
win = {ws_row = 24, ws_col = 80, ws_xpixel = 499, ws_ypixel = 316}
fp = (FILE *) 0x804a84c
ch = -1
tflag = 0
xflag = 0
p = 0xbdbdaef0 ",\036\v"
#2 0x080489e6 in ___start ()
>Fix:
Index: column.c
===================================================================
RCS file: /cvsroot/src/usr.bin/column/column.c,v
retrieving revision 1.12
diff -b -u -r1.12 column.c
--- column.c 17 Feb 2005 17:17:25 -0000 1.12
+++ column.c 17 Dec 2005 15:52:55 -0000
@@ -54,6 +54,8 @@
#include <string.h>
#include <unistd.h>
+#define TAB 8
+
void c_columnate(void);
void *emalloc(int);
void input(FILE *);
@@ -120,6 +122,7 @@
if (!entries)
exit(eval);
+ maxlength = (maxlength + TAB) & ~(TAB - 1);
if (tflag)
maketbl();
else if (maxlength >= termwidth)
@@ -131,14 +134,12 @@
exit(eval);
}
-#define TAB 8
void
c_columnate(void)
{
int chcnt, col, cnt, endcol, numcols;
char **lp;
- maxlength = (maxlength + TAB) & ~(TAB - 1);
numcols = termwidth / maxlength;
endcol = maxlength;
for (chcnt = col = 0, lp = list;; ++lp) {
@@ -166,7 +167,6 @@
{
int base, chcnt, cnt, col, endcol, numcols, numrows, row;
- maxlength = (maxlength + TAB) & ~(TAB - 1);
numcols = termwidth / maxlength;
numrows = entries / numcols;
if (entries % numcols)