Improvement on the existing directory traversal patch, fixes the case

where the path component includes a quoted slash.
This commit is contained in:
brad 2003-08-17 23:48:40 +00:00
parent 0cd878db07
commit a937c7a5d3
3 changed files with 58 additions and 12 deletions

View File

@ -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/ \

View File

@ -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"

View File

@ -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-