diff --git a/archivers/zip/Makefile b/archivers/zip/Makefile index eb392156abf8..8deeb930dd21 100644 --- a/archivers/zip/Makefile +++ b/archivers/zip/Makefile @@ -1,43 +1,43 @@ PORTNAME= zip PORTVERSION= 3.0 -PORTREVISION= 5 +PORTREVISION= 6 CATEGORIES= archivers MASTER_SITES= SF/info${PORTNAME}/Zip%203.x%20%28latest%29/${PORTVERSION} DISTNAME= ${PORTNAME}${PORTVERSION:S/.//g} MAINTAINER= fuz@FreeBSD.org COMMENT= Create/update ZIP files compatible with PKZIP WWW= https://infozip.sourceforge.net/Zip.html # License is BSD-based, but not identical, so install with documentation LICENSE= BSD3CLAUSE LICENSE_FILE= ${WRKSRC}/LICENSE USES= cpe CPE_VENDOR= info-zip_project OPTIONS_DEFINE= DOCS CFLAGS+= -Wno-deprecated-non-prototype MAKE_ARGS= CC="${CC}" CFLAGS="${CFLAGS}" MAKEFILE= unix/Makefile ALL_TARGET= generic PLIST_FILES= bin/zip bin/zipcloak bin/zipnote bin/zipsplit \ share/man/man1/zip.1.gz share/man/man1/zipcloak.1.gz \ share/man/man1/zipnote.1.gz share/man/man1/zipsplit.1.gz PORTDOCS= * do-install: .for p in ${PLIST_FILES:Mbin*:T} ${INSTALL_PROGRAM} ${WRKSRC}/${p} ${STAGEDIR}${PREFIX}/bin ${INSTALL_MAN} ${WRKSRC}/man/${p}.1 ${STAGEDIR}${PREFIX}/share/man/man1 .endfor do-install-DOCS-on: @${MKDIR} ${STAGEDIR}${DOCSDIR} cd ${WRKSRC}/ && ${INSTALL_DATA} CHANGES README* TODO WHATSNEW WHERE ${STAGEDIR}${DOCSDIR} .include diff --git a/archivers/zip/files/patch-zip.c b/archivers/zip/files/patch-zip.c index d81182e3baf1..fb7e7a7e2a03 100644 --- a/archivers/zip/files/patch-zip.c +++ b/archivers/zip/files/patch-zip.c @@ -1,43 +1,262 @@ From: Santiago Vila Subject: Use format specifier %s to print strings, not the string itself Bug-Debian: https://bugs.debian.org/673476 X-Debian-version: 3.0-5 From: Florent 'Skia' Jacquet Subject: Fix buffer overflow when using '-T -TT' Bug-Debian: https://bugs.debian.org/1093629 Bug-Ubuntu: https://launchpad.net/bugs/2093024 Forwarded: https://sourceforge.net/p/infozip/bugs/81/ strlen(unzip_path) + strlen(zipname) + " " + "'" + "'" + '\0' The additional space required in the `cmd` buffer is 4, not 3. +From: Paul Marquess +Subject: Fix command injection issue +Bug-Debian: https://bugs.debian.org/1143866 +X-Debian-version: 3.0-16 + --- zip.c.orig 2008-07-05 16:34:06 UTC +++ zip.c -@@ -1028,7 +1028,7 @@ local void help_extended() +@@ -122,6 +122,7 @@ local int finish OF((int)); + + local void freeup OF((void)); + local int finish OF((int)); ++local char *quote_arg(char *instring); + #if (!defined(MACOS) && !defined(WINDLL)) + local void handler OF((int)); + local void license OF((void)); +@@ -1028,7 +1029,7 @@ local void help_extended() for (i = 0; i < sizeof(text)/sizeof(char *); i++) { - printf(text[i]); + printf("%s", text[i]); putchar('\n'); } #ifdef DOS -@@ -1225,7 +1225,7 @@ local void version_info() +@@ -1225,7 +1226,7 @@ local void version_info() CR_MAJORVER, CR_MINORVER, CR_BETA_VER, CR_VERSION_DATE); for (i = 0; i < sizeof(cryptnote)/sizeof(char *); i++) { - printf(cryptnote[i]); + printf("%s", cryptnote[i]); putchar('\n'); } ++i; /* crypt support means there IS at least one compilation option */ -@@ -1437,7 +1437,7 @@ local void check_zipfile(zipname, zippath) +@@ -1323,6 +1324,134 @@ local int check_unzip_version(unzippath) + return 1; + } + ++ ++/* quote_arg() ++ * ++ * Add quotation and/or escapes to a shell (VMS: DCL) argument string ++ * appropriate to the local operating system or shell (Unix, Windows, ++ * etc.). This is mainly used to build the command line to pass to ++ * UnZip (or other application when -TT used) to test an archive. ++ * Return malloc()'d result. ++ * ++ * All: Add " at beginning and end. ++ * MSDOS: % -> "^%" ++ * " -> \"" ++ * Unix: ! -> "'!'" ++ * $ -> \$ ++ * \ -> \\ ++ * ` -> \` ++ * Non-VMS: " -> \" ++ * VMS: " -> """ ++ * ++ * On VMS, quoted double apostrophes are also special. Currently not ++ * handled. (How? Quotation marks are needed for (upper-)case ++ * preservation. Double apostrophes in quotation marks are interpreted ++ * (symbol evaluation). SMS sees no way to handle "fr''ed". "fr'""'ed" ++ * becomes >fr'"'ed<, for example.) Not a problem for file specs, but ++ * imposes a restriction on passwords. ++ */ ++#ifndef NO_PROTO ++local char *quote_arg(char *instring) ++#else ++local char *quote_arg(instring) ++ char *instring; ++#endif ++{ ++ int i; ++ int j; ++ char *tempstring; ++ char *outstring; ++ char c; ++ ++ if (instring == NULL) ++ return NULL; ++ ++# ifdef MSDOS ++# define QA_FACTOR 4 /* Worst case (MSDOS): % -> "^%" */ ++ ++# else /* not MSDOS */ ++# ifdef VMS ++# define QA_FACTOR 3 /* Worst case (VMS): " -> """ */ ++ ++# else /* not MSDOS or VMS */ ++# define QA_FACTOR 5 /* Worst case (Unix): ! -> "'!'" */ ++# endif /* VMS [else] */ ++# endif /* MSDOS [else] */ ++ ++# define QA_INCR 2 /* Surrounding quotation marks. */ ++ ++ i = QA_FACTOR * (int)strlen(instring) + QA_INCR + 1; ++ if ((tempstring = (char *)malloc(i)) == NULL) { ++ ZIPERR(ZE_MEM, "quote_arg"); ++ } ++ ++ j = 0; ++ ++ tempstring[j++] = '\"'; /* Surrounding quotation mark (start). */ ++ ++ for (i = 0; instring[i]; i++) { ++ c = instring[i]; ++ ++# ifdef MSDOS /* or Windows */ ++ if (c == '%') /* Percent. */ ++ { ++ tempstring[j++] = '"'; /* Add (closing) quotation mark. */ ++ tempstring[j++] = '^'; /* Add caret escape. */ ++ tempstring[j++] = '%'; /* Original character (%). */ ++ c = '"'; /* Prepare (re-opening) quotation mark. */ ++ } ++ else if (c == '"') /* Quotation mark. */ ++ { ++ tempstring[j++] = '\\'; /* Add backslash (escape). */ ++ tempstring[j++] = '"'; /* Add quote (acts as closing and literal). */ ++ } ++# else /* not def MSDOS */ ++ ++# ifdef VMS ++ if (c == '"') /* Quotation mark. */ ++ { ++ tempstring[j++] = '"'; /* Add two quotation marks. */ ++ tempstring[j++] = '"'; ++ } ++# else /* not def VMS */ ++ ++ /* UNIX is default for others */ ++ ++ if (c == '"') /* Quotation mark. */ ++ { ++ tempstring[j++] = '\\'; /* Add backslash (escape). */ ++ } ++ else if (c == '!') /* Exclamation. (Inefficient.) */ ++ { ++ tempstring[j++] = '"'; /* Add (closing) quotation mark. */ ++ tempstring[j++] = '\''; /* Add (opening) apostrophe. */ ++ tempstring[j++] = '!'; /* Original character (!). */ ++ tempstring[j++] = '\''; /* Add (closing) apostrophe. */ ++ c = '"'; /* Prepare (re-opening) quotation mark. */ ++ } ++ else if ((c == '$') || /* Dollar sign. */ ++ (c == '`') || /* Grave accent (backtick). */ ++ (c == '\\')) /* Backslash. */ ++ { ++ tempstring[j++] = '\\'; /* Add backslash (escape). */ ++ } ++ ++# endif /* def VMS [else] */ ++# endif /* def MSDOS [else] */ ++ ++ tempstring[j++] = c; /* Original (or other last) character. */ ++ } ++ ++ tempstring[j++] = '\"'; /* Surrounding quotation mark (end). */ ++ ++ tempstring[j] = '\0'; ++ /* outstring = string_dup(tempstring, "quote_arg", NO_FLUFF); */ ++ outstring = strdup(tempstring); ++ free(tempstring); ++ ++ return outstring; ++} ++ + local void check_zipfile(zipname, zippath) + char *zipname; + char *zippath; +@@ -1424,11 +1553,15 @@ local void check_zipfile(zipname, zippath) + + #else /* (MSDOS && !__GO32__) || __human68k__ */ + char *cmd; ++ char *qzipname; + int result; + + /* Tell picky compilers to shut up about unused variables */ + zippath = zippath; + ++ /* Quote each arg (and add appropriate escapes). */ ++ qzipname = quote_arg(zipname); ++ + if (unzip_path) { + /* user gave us a path to some unzip (may not be UnZip) */ + char *here; +@@ -1437,7 +1570,7 @@ local void check_zipfile(zipname, zippath) /* Replace first {} with archive name. If no {} append name to string. */ here = strstr(unzip_path, "{}"); - if ((cmd = malloc(strlen(unzip_path) + strlen(zipname) + 3)) == NULL) { -+ if ((cmd = malloc(strlen(unzip_path) + strlen(zipname) + 4)) == NULL) { ++ if ((cmd = malloc(strlen(unzip_path) + strlen(qzipname) + 4)) == NULL) { + ziperr(ZE_MEM, "building command string for testing archive"); + } + +@@ -1447,32 +1580,20 @@ local void check_zipfile(zipname, zippath) + strcpy(cmd, unzip_path); + cmd[len] = '\0'; + strcat(cmd, " "); +-# ifdef UNIX +- strcat(cmd, "'"); /* accept space or $ in name */ +- strcat(cmd, zipname); +- strcat(cmd, "'"); +-# else +- strcat(cmd, zipname); +-# endif ++ strcat(cmd, qzipname); + strcat(cmd, " "); + strcat(cmd, here + 2); + } else { + /* No {} so append temp name to end */ + strcpy(cmd, unzip_path); + strcat(cmd, " "); +-# ifdef UNIX +- strcat(cmd, "'"); /* accept space or $ in name */ +- strcat(cmd, zipname); +- strcat(cmd, "'"); +-# else +- strcat(cmd, zipname); +-# endif ++ strcat(cmd, qzipname); + } + free(unzip_path); + unzip_path = NULL; + + } else { +- if ((cmd = malloc(20 + strlen(zipname))) == NULL) { ++ if ((cmd = malloc(20 + strlen(qzipname))) == NULL) { ziperr(ZE_MEM, "building command string for testing archive"); } +@@ -1484,14 +1605,11 @@ local void check_zipfile(zipname, zippath) + if (check_unzip_version("unzip") == 0) + ZIPERR(ZE_TEST, zipfile); + +-# ifdef UNIX +- strcat(cmd, "'"); /* accept space or $ in name */ +- strcat(cmd, zipname); +- strcat(cmd, "'"); +-# else +- strcat(cmd, zipname); +-# endif ++ strcat(cmd, qzipname); + } ++ ++ if (qzipname) ++ free(qzipname); + + result = system(cmd); + # ifdef VMS