Subject: bin/28779: prepend_gzip() dumps core
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: None <qhwt+nbsd@les.ath.cx>
List: netbsd-bugs
Date: 12/25/2004 04:12:00
>Number:         28779
>Category:       bin
>Synopsis:       prepend_gzip() dumps core
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Sat Dec 25 04:12:00 +0000 2004
>Originator:     YONETANI Tomokazu
>Release:        
>Organization:
>Environment:
NetBSD gzl.local 2.99.11 NetBSD 2.99.11 (GZL) #14: Thu Dec 16 15:59:45 JST 2004  qhwt@gzl.local:/usr/obj/sys/arch/i386/compile/GZL i386

>Description:
prepend_gzip() tries to parse string beyond strdup'ed area when it
assembles its own version of argv array(the second for() loop).
When the inner loop encountered a NUL character and terminated, the
outer loop compares *s against '\0' AFTER incrementing the pointer
because of the loop condition, requiring two consecutive NUL's
at the end of the string.
This is similar to a problem fixed in revision 1.17 of gzip.c.
The problem was originally discovered on DragonFly, which recently
imported NetBSD version of gzip, but it also reproduced on a
recent version of NetBSD.

>How-To-Repeat:
Following command should reproduce the problem
(assuming you're using phk-malloc derived from FreeBSD):

$ env MALLOC_OPTIONS=AJ GZIP=-9 gzip

>Fix:
Index: gzip.c
===================================================================
RCS file: /netbsd/cvs/src/usr.bin/gzip/gzip.c,v
retrieving revision 1.69
diff -u -r1.69 gzip.c
--- gzip.c	8 Dec 2004 06:38:40 -0000	1.69
+++ gzip.c	25 Dec 2004 04:06:46 -0000
@@ -475,6 +475,8 @@
 				*s = 0;
 				break;
 			}
+		if (*s == '\0')
+			break;
 	}
 
 	/* copy the original arguments and a NULL */