diff --git a/infozip/infozip.patch b/infozip/infozip.patch index 400a1a1c73..ff57a2fb9b 100644 --- a/infozip/infozip.patch +++ b/infozip/infozip.patch @@ -9,3 +9,90 @@ [ $? -eq 0 ] && CPP="${CPP} -DNO_UNDERLINE" if eval "$CPP crc_i386.S > _crc_i386.s 2>/dev/null"; then if eval "$CC -c _crc_i386.s >/dev/null 2>/dev/null" && [ -f _crc_i386.o ] + +http://cve.mitre.org/cgi-bin/cvename.cgi?name=CAN-2003-0282 + Directory traversal vulnerability in UnZip 5.50 allows attackers to + overwrite arbitrary files via invalid characters between two . (dot) + characters, which are filtered and result in a ".." sequence. + +--- unzip-5.50/unix/unix.c.orig 2002-01-21 17:54:42.000000000 -0500 ++++ unzip-5.50/unix/unix.c 2003-06-11 18:35:38.000000000 -0400 +@@ -421,7 +421,8 @@ + */ + { + char pathcomp[FILNAMSIZ]; /* path-component buffer */ +- char *pp, *cp=(char *)NULL; /* character pointers */ ++ char *pp, *cp=(char *)NULL, /* character pointers */ ++ *dp=(char *)NULL; + 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 @@ + #endif + int quote = FALSE; /* flags */ + int killed_ddot = FALSE; /* is set when skipping "../" 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 @@ + while ((workch = (uch)*cp++) != 0) { + + if (quote) { /* if character quoted, */ ++ if ((pp == pathcomp) && (workch == '.')) ++ /* Oh no you don't... */ ++ goto ddot_hack; + *pp++ = (char)workch; /* include it literally */ + quote = FALSE; + } else +@@ -481,15 +486,44 @@ + break; + + case '.': +- if (pp == pathcomp) { /* nothing appended yet... */ ++ if (pp == pathcomp) { ++ddot_hack: ++ /* nothing appended yet... */ + if (*cp == '/') { /* don't bother appending "./" to */ + ++cp; /* the path: skip behind the '/' */ + break; +- } else if (!uO.ddotflag && *cp == '.' && cp[1] == '/') { +- /* "../" dir traversal detected */ +- cp += 2; /* skip over behind the '/' */ +- killed_ddot = TRUE; /* set "show message" flag */ +- break; ++ } else if (!uO.ddotflag) { ++ ++ /* ++ * SECURITY: Skip past control characters if the user ++ * didn't OK use of absolute pathnames. lhh - this is ++ * a very quick, ugly, inefficient fix. ++ */ ++ dp = cp; ++ do { ++ workch = (uch)(*dp); ++ if (workch == '/' && snarf_ddot) { ++ /* "../" dir traversal detected */ ++ cp = dp + 1; /* skip past the '/' */ ++ killed_ddot = TRUE; /* set "show msg" flag */ ++ break; ++ } else if (workch == '.' && !snarf_ddot) { ++ snarf_ddot = TRUE; ++ } else if (isprint(workch) || ++ ((workch > 127) && (workch <= 254))) { ++ /* ++ * Since we found a printable, non-ctrl char, ++ * we can stop looking for '../', the amount ++ * in ../! ++ */ ++ break; ++ } ++ ++ dp++; ++ } while (*dp != 0); ++ ++ if (killed_ddot) ++ break; + } + } + *pp++ = '.';