diff options
author | simon <simon@FreeBSD.org> | 2005-06-08 21:25:19 +0000 |
---|---|---|
committer | simon <simon@FreeBSD.org> | 2005-06-08 21:25:19 +0000 |
commit | cf5f249f1edd1b70094557e8a7a000ac49eb94c5 (patch) | |
tree | 886d55bcc36a3ec22e591fe80c5f31676df689fa /gnu | |
parent | 3d445ed2f2296f8e48f68e61e24de3eb40e4bdcc (diff) | |
download | FreeBSD-src-cf5f249f1edd1b70094557e8a7a000ac49eb94c5.zip FreeBSD-src-cf5f249f1edd1b70094557e8a7a000ac49eb94c5.tar.gz |
Correct directory traversal and race condition vulnerabilities in gzip.
Security: FreeBSD-SA-05:11.gzip
Security: CAN-2005-0988, CAN-2005-1228
Obtained from: Steve Grubb via RedHat, Debian
Approved by: nectar
Diffstat (limited to 'gnu')
-rw-r--r-- | gnu/usr.bin/gzip/gzip.c | 18 |
1 files changed, 10 insertions, 8 deletions
diff --git a/gnu/usr.bin/gzip/gzip.c b/gnu/usr.bin/gzip/gzip.c index 06b0a32..a9af12c 100644 --- a/gnu/usr.bin/gzip/gzip.c +++ b/gnu/usr.bin/gzip/gzip.c @@ -830,8 +830,11 @@ local void treat_file(iname) } close(ifd); - if (!to_stdout && close(ofd)) { - write_error(); + if (!to_stdout) { + /* Copy modes, times, ownership, and remove the input file */ + copy_stat(&istat); + if (close(ofd)) + write_error(); } if (method == -1) { if (!to_stdout) unlink (ofname); @@ -851,10 +854,6 @@ local void treat_file(iname) } fprintf(stderr, "\n"); } - /* Copy modes, times, ownership, and remove the input file */ - if (!to_stdout) { - copy_stat(&istat); - } } /* ======================================================================== @@ -1258,6 +1257,7 @@ local int get_method(in) /* Copy the base name. Keep a directory prefix intact. */ char *p = basename(ofname); char *base = p; + char *base2; for (;;) { *p = (char)get_char(); if (*p++ == '\0') break; @@ -1265,6 +1265,8 @@ local int get_method(in) error("corrupted input -- file name too large"); } } + base2 = basename (base); + strcpy(base, base2); /* If necessary, adapt the name to local OS conventions: */ if (!list) { MAKE_LEGAL_NAME(base); @@ -1637,12 +1639,12 @@ local void copy_stat(ifstat) reset_times(ofname, ifstat); #endif /* Copy the protection modes */ - if (chmod(ofname, ifstat->st_mode & 07777)) { + if (fchmod(ofd, ifstat->st_mode & 07777)) { WARN((stderr, "%s: ", progname)); if (!quiet) perror(ofname); } #ifndef NO_CHOWN - chown(ofname, ifstat->st_uid, ifstat->st_gid); /* Copy ownership */ + (void) fchown(ofd, ifstat->st_uid, ifstat->st_gid); /* Copy ownership */ #endif remove_ofname = 0; /* It's now safe to remove the input file: */ |