Subject: bin/19722: fix for 3 uncompress(1) bugs that delete/truncate the wrong file
To: None <gnats-bugs@gnats.netbsd.org>
From: Giorgos Keramidas <keramida@freebsd.org>
List: netbsd-bugs
Date: 01/07/2003 12:20:37
>Number: 19722
>Category: bin
>Synopsis: fix for 3 uncompress(1) bugs that delete/truncate the wrong file
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: bin-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Tue Jan 07 02:21:00 PST 2003
>Closed-Date:
>Last-Modified:
>Originator:
>Release: NetBSD 1.6
>Organization:
>Environment:
System: NetBSD spe143.testdrive.compaq.com 1.6 NetBSD 1.6 (GENERIC) #0: Sun Sep 8 19:43:40 UTC 2002 autobuild@tgm.daemon.org:/autobuild/i386/OBJ/autobuild/src/sys/arch/i386/compile/GENERIC i386
Architecture: i386
Machine: i386
>Description:
The attached diff fixes two bugs in uncompress(1) that are present in
both FreeBSD & NetBSD. The output file of decompress() in compress.c
should not be unlinked in the following cases:
- if the input file (the .Z one) cannot be opened for reading.
- if the input file exists but fread() after zopen() fails.
The attached diff also fixes a minor bug that is caused by trying to
open the output file before checking if the input file exists. The
output file shouldn't be opened first, because it will be truncated.
By moving the fopen() that truncates the output file further down, we
make sure that the output file isn't unnecessarily truncated if the
input file doesn't exist.
>How-To-Repeat:
The following two sample sessions from a NetBSD 1.6 installation at
Compaq's testdrive installations show the bugs in action:
spe143-> rm lala.Z
spe143-> ls -l lala*
ls: No match.
spe143-> touch lala
spe143-> ls -l lala*
-rw-r--r-- 1 gk736 nis 0 Jan 6 23:22 lala
spe143-> ln -s compress uncompress
spe143-> ./uncompress -f lala
uncompress: lala.Z: No such file or directory
spe143-> ls -l lala*
ls: No match.
spe143->
spe143-> cp /etc/rc.conf lala.Z
spe143-> touch lala
spe143-> ls -l lala*
-rw-r--r-- 1 gk736 nis 0 Jan 6 23:24 lala
-rw-r--r-- 1 gk736 nis 815 Jan 6 23:24 lala.Z
spe143-> ./uncompress -f lala
uncompress: lala.Z: Inappropriate file type or format
spe143-> ls -l lala*
-rw-r--r-- 1 gk736 nis 815 Jan 6 23:24 lala.Z
spe143->
>Fix:
%%%
Index: compress.c
===================================================================
RCS file: /cvsroot/src/usr.bin/compress/compress.c,v
retrieving revision 1.19
diff -u -r1.19 compress.c
--- compress.c 2002/05/26 22:21:22 1.19
+++ compress.c 2003/01/07 04:32:57
@@ -317,19 +317,15 @@
oreg = 0;
ifp = ofp = NULL;
- if ((ofp = fopen(out, "w")) == NULL) {
- cwarn("%s", out);
- return;
- }
-
if ((ifp = zopen(in, "r", bits)) == NULL) {
cwarn("%s", in);
- goto err;
+ return;
}
if (!isstdin) {
if (stat(in, &sb)) {
cwarn("%s", in);
- goto err;
+ (void)fclose(ifp);
+ return;
}
if (!S_ISREG(sb.st_mode))
isreg = 0;
@@ -337,6 +333,21 @@
isreg = 1;
} else
isreg = 0;
+
+ if ((nr = fread(buf, 1, sizeof(buf), ifp)) == 0) {
+ cwarn("%s", in);
+ (void)fclose(ifp);
+ return;
+ }
+ if ((ofp = fopen(out, "w")) == NULL) {
+ cwarn("%s", out);
+ (void)fclose(ifp);
+ return;
+ }
+ if (fwrite(buf, 1, nr, ofp) != nr) {
+ cwarn("%s", out);
+ goto err;
+ }
while ((nr = fread(buf, 1, sizeof(buf), ifp)) != 0)
if (fwrite(buf, 1, nr, ofp) != nr) {
%%%
>Release-Note:
>Audit-Trail:
>Unformatted: