Package: gzip Version: 1.3.5-13 Severity: critical Tags: patch Justification: causes serious data loss
gzip must check that closing the output file succeeds before removing the input file, since on an NFS filesystem write failures may only be reported at close time (see the close(2) man page). Indeed in our environment we are seeing this problem with NFS and disk quotas. This results in loss of the input file, despite the fact that gzip reports an error and the output file is truncated. I've attached a proposed patch. In the original code, copy_stat() has the side-effect of removing the input file. Here I have moved the unlink out of that function and to below the close of the output file. Matt -- System Information: Debian Release: testing/unstable Architecture: i386 (i686) Shell: /bin/sh linked to /bin/bash Kernel: Linux 2.6.16.4-general Locale: LANG=en_AU.UTF-8, LC_CTYPE=en_AU.UTF-8 (charmap=UTF-8) Versions of packages gzip depends on: hi debianutils 2.15.2 Miscellaneous utilities specific t hi libc6 2.3.5-8 GNU C Library: Shared libraries an gzip recommends no packages. -- no debconf information
--- gzip.c.orig 2006-05-10 15:12:34.000000000 +1000 +++ gzip.c 2006-05-10 15:45:35.000000000 +1000 @@ -882,10 +882,21 @@ close(ifd); if (!to_stdout) { - /* Copy modes, times, ownership, and remove the input file */ - copy_stat(&istat); - if (close(ofd)) - write_error(); + /* Copy modes, times, and ownership */ + copy_stat(&istat); + if (close(ofd)) + write_error(); + remove_ofname = 0; + + /* It's now safe to remove the input file: */ + if (xunlink (ifname)) { + int e = errno; + WARN((stderr, "%s: ", progname)); + if (!quiet) { + errno = e; + perror(ifname); + } + } } if (method == -1) { if (!to_stdout) xunlink (ofname); @@ -1745,16 +1756,6 @@ #ifndef NO_CHOWN fchown(ofd, ifstat->st_uid, ifstat->st_gid); /* Copy ownership */ #endif - remove_ofname = 0; - /* It's now safe to remove the input file: */ - if (xunlink (ifname)) { - int e = errno; - WARN((stderr, "%s: ", progname)); - if (!quiet) { - errno = e; - perror(ifname); - } - } } #if ! NO_DIR