Subject: bin/28995: gzip -c accesses uninit. var for timestamp
To: None <gnats-admin@netbsd.org, netbsd-bugs@netbsd.org>
From: None <jhein@timing.com>
List: netbsd-bugs
Date: 01/18/2005 03:27:00
>Number:         28995
>Category:       bin
>Synopsis:       gzip -c accesses uninit. var for timestamp
>Confidential:   no
>Severity:       non-critical
>Priority:       medium
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Tue Jan 18 03:27:00 +0000 2005
>Originator:     John Hein
>Release:        HEAD
>Organization:
Timing Solutions Copr.
>Environment:
>Description:
When using gzip -c, an uninitialized value for the timestamp is output.
>How-To-Repeat:
% touch -t 200501101600 xx
% ls -l xx
-rw-r--r--  1 root  wheel  0 Jan 10 15:00 xx

% gzip -Nc xx > x.gz
% gzip -Nvl x.gz
method  crc     date  time    compressed uncompressed  ratio uncompressed_name
defla 00000000 Jan  1 00:11           23            0 -99.9% xx

(note the wrong date reported - this is random memory in a time_t in fact)

% gzip -Nd x.gz
% ls -l xx
-rw-r--r--  1 root  tsc  0 Jan  1  1970 xx


>Fix:
Pardon the format if this patch doesn't come out right.  I'm using the web form.  I can email the patch if needed.

In summary, always fill the stat struct when compressing a file even if using -c.

I left the link warning in the 'cflag == 0' block since gnu gzip doesn't seem to warn or care about a file with links if using -c.  I'm not sure why it doesn't.  It could be considered to be wrong behavior.  If you choose, move the link warning outside the 'cflag == 0' block, too.

--- gzip.c.1.69	Tue Jan 18 02:13:50 2005
+++ gzip.c	Tue Jan 18 02:53:31 2005
@@ -1125,16 +1125,17 @@
 		return -1;
 	}
 
+#ifndef SMALL
+	stat(file, &isb);
+#endif
 	if (cflag == 0) {
 #ifndef SMALL
-		if (stat(file, &isb) == 0) {
-			if (isb.st_nlink > 1 && fflag == 0) {
-				maybe_warnx("%s has %d other link%s -- "
-					    "skipping", file, isb.st_nlink - 1,
-					    isb.st_nlink == 1 ? "" : "s");
-				close(in);
-				return -1;
-			}
+		if (isb.st_nlink > 1 && fflag == 0) {
+			maybe_warnx("%s has %d other link%s -- "
+				    "skipping", file, isb.st_nlink - 1,
+			    isb.st_nlink == 1 ? "" : "s");
+			close(in);
+			return -1;
 		}
 
 		if (fflag == 0 && (suff = check_suffix(file, 0))