From a937c7a5d3c14606859d4ccd52d8099904e792aa Mon Sep 17 00:00:00 2001 From: brad Date: Sun, 17 Aug 2003 23:48:40 +0000 Subject: [PATCH] Improvement on the existing directory traversal patch, fixes the case where the path component includes a quoted slash. --- archivers/unzip/Makefile | 4 +- archivers/unzip/patches/patch-man_unzip_1 | 18 +++++++++ archivers/unzip/patches/patch-unix_unix_c | 48 ++++++++++++++++++----- 3 files changed, 58 insertions(+), 12 deletions(-) create mode 100644 archivers/unzip/patches/patch-man_unzip_1 diff --git a/archivers/unzip/Makefile b/archivers/unzip/Makefile index c3f4c4ec365..994c1ece9de 100644 --- a/archivers/unzip/Makefile +++ b/archivers/unzip/Makefile @@ -1,10 +1,10 @@ -# $OpenBSD: Makefile,v 1.31 2003/07/02 16:03:59 brad Exp $ +# $OpenBSD: Makefile,v 1.32 2003/08/17 23:48:40 brad Exp $ COMMENT= "extract, list & test files in a ZIP archive" VERSION= 5.50 DISTNAME= unzip${VERSION:S/.//} -PKGNAME= unzip-${VERSION}p1 +PKGNAME= unzip-${VERSION}p2 CATEGORIES= archivers MASTER_SITES= ftp://ftp.info-zip.org/pub/infozip/src/ \ ftp://ftp.uu.net/pub/archiving/zip/src/ \ diff --git a/archivers/unzip/patches/patch-man_unzip_1 b/archivers/unzip/patches/patch-man_unzip_1 new file mode 100644 index 00000000000..47938bce58a --- /dev/null +++ b/archivers/unzip/patches/patch-man_unzip_1 @@ -0,0 +1,18 @@ +$OpenBSD: patch-man_unzip_1,v 1.1 2003/08/17 23:48:40 brad Exp $ +--- man/unzip.1.orig 2002-02-10 17:09:20.000000000 -0500 ++++ man/unzip.1 2003-08-17 19:25:19.000000000 -0400 +@@ -396,7 +396,13 @@ version 5.50) prevents \fIunzip\fP from + \fB\-:\fP option lets \fIunzip\fP switch back to its previous, more liberal + behaviour, to allow exact extraction of (older) archives that used ``../'' + components to create multiple directory trees at the level of the current +-extraction folder. ++extraction folder. Use of this will not enable writing explicitly to the ++root directory (``/''). To do this, it is necessary to unzip the file from ++within the root directory itself. However, when the \fB\-:\fP option is ++specified, it is still possible to write to implicitly write to the root ++directory by specifiying enough ``../'' path components within the zip file. ++Use this option with extreme caution. ++ + .PD + .\" ========================================================================= + .SH "ENVIRONMENT OPTIONS" diff --git a/archivers/unzip/patches/patch-unix_unix_c b/archivers/unzip/patches/patch-unix_unix_c index afde6de161d..43a70fb44c3 100644 --- a/archivers/unzip/patches/patch-unix_unix_c +++ b/archivers/unzip/patches/patch-unix_unix_c @@ -1,6 +1,6 @@ -$OpenBSD: patch-unix_unix_c,v 1.1 2003/07/02 16:03:59 brad Exp $ ---- unix/unix.c.orig Mon Jan 21 17:54:42 2002 -+++ unix/unix.c Wed Jul 2 11:48:50 2003 +$OpenBSD: patch-unix_unix_c,v 1.2 2003/08/17 23:48:40 brad Exp $ +--- unix/unix.c.orig 2002-01-21 17:54:42.000000000 -0500 ++++ unix/unix.c 2003-08-17 19:25:19.000000000 -0400 @@ -421,7 +421,8 @@ int mapname(__G__ renamed) */ { @@ -11,25 +11,35 @@ $OpenBSD: patch-unix_unix_c,v 1.1 2003/07/02 16:03:59 brad Exp $ char *lastsemi=(char *)NULL; /* pointer to last semi-colon in pathcomp */ #ifdef ACORN_FTYPE_NFS char *lastcomma=(char *)NULL; /* pointer to last comma in pathcomp */ -@@ -429,6 +430,7 @@ int mapname(__G__ renamed) +@@ -429,6 +430,8 @@ int mapname(__G__ renamed) #endif int quote = FALSE; /* flags */ int killed_ddot = FALSE; /* is set when skipping "../" pathcomp */ ++ int killed_qslash = FALSE; /* is set when skipping "^V/" pathcomp */ + int snarf_ddot = FALSE; /* Is set while scanning for "../" */ int error = MPN_OK; register unsigned workch; /* hold the character being tested */ -@@ -467,6 +469,9 @@ int mapname(__G__ renamed) +@@ -467,6 +470,18 @@ int mapname(__G__ renamed) while ((workch = (uch)*cp++) != 0) { if (quote) { /* if character quoted, */ -+ if ((pp == pathcomp) && (workch == '.')) -+ /* Oh no you don't... */ -+ goto ddot_hack; ++ if (pp == pathcomp) { ++ quote = FALSE; ++ if (workch == '.') ++ /* Oh no you don't... */ ++ goto ddot_hack; ++ if (workch == '/') { ++ /* We *never* allow quote-slash at the beginning */ ++ killed_qslash = TRUE; ++ continue; ++ } ++ } ++ *pp++ = (char)workch; /* include it literally */ quote = FALSE; } else -@@ -481,15 +486,44 @@ int mapname(__G__ renamed) +@@ -481,15 +496,45 @@ int mapname(__G__ renamed) break; case '.': @@ -50,7 +60,8 @@ $OpenBSD: patch-unix_unix_c,v 1.1 2003/07/02 16:03:59 brad Exp $ + /* + * SECURITY: Skip past control characters if the user + * didn't OK use of absolute pathnames. lhh - this is -+ * a very quick, ugly, inefficient fix. ++ * a very quick, ugly, inefficient fix; it traverses ++ * the WHOLE path, eating up these as it comes to it. + */ + dp = cp; + do { @@ -80,3 +91,20 @@ $OpenBSD: patch-unix_unix_c,v 1.1 2003/07/02 16:03:59 brad Exp $ } } *pp++ = '.'; +@@ -534,6 +579,16 @@ int mapname(__G__ renamed) + error = (error & MPN_MASK) | PK_WARN; + } + ++ /* Show warning when stripping insecure quoted-slash at beginning of ++ path components */ ++ if (killed_qslash && QCOND2) { ++ Info(slide, 0, ((char *)slide, ++ "warning: skipped root directory component(s) in %s\n", ++ FnFilter1(G.filename))); ++ if (!(error & ~MPN_MASK)) ++ error = (error & MPN_MASK) | PK_WARN; ++ } ++ + /*--------------------------------------------------------------------------- + Report if directory was created (and no file to create: filename ended + in '/'), check name to be sure it exists, and combine path and name be-