Version in base suite: 3.0-15 Base version: zip_3.0-15 Target version: zip_3.0-15+deb13u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/z/zip/zip_3.0-15.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/z/zip/zip_3.0-15+deb13u1.dsc changelog | 6 patches/fix-command-injection.patch | 231 ++++++++++++++++++++++++++++++++++++ patches/series | 1 3 files changed, 238 insertions(+) dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpzdbkwxaw/zip_3.0-15.dsc: no acceptable signature found dpkg-source: warning: cannot verify inline signature for /srv/release.debian.org/tmp/tmpzdbkwxaw/zip_3.0-15+deb13u1.dsc: no acceptable signature found diff -Nru zip-3.0/debian/changelog zip-3.0/debian/changelog --- zip-3.0/debian/changelog 2025-04-25 20:55:00.000000000 +0000 +++ zip-3.0/debian/changelog 2026-08-10 22:20:00.000000000 +0000 @@ -1,3 +1,9 @@ +zip (3.0-15+deb13u1) trixie-security; urgency=high + + * Fix command injection issue. Closes: #1143866. + + -- Santiago Vila Tue, 11 Aug 2026 00:20:00 +0200 + zip (3.0-15) unstable; urgency=medium * Add debian/source/lintian-overrides for *.a files. diff -Nru zip-3.0/debian/patches/fix-command-injection.patch zip-3.0/debian/patches/fix-command-injection.patch --- zip-3.0/debian/patches/fix-command-injection.patch 1970-01-01 00:00:00.000000000 +0000 +++ zip-3.0/debian/patches/fix-command-injection.patch 2026-08-10 22:20:00.000000000 +0000 @@ -0,0 +1,231 @@ +From: Paul Marquess +Subject: Fix command injection issue +Bug-Debian: https://bugs.debian.org/1143866 +X-Debian-version: 3.0-16 + +--- a/zip.c ++++ b/zip.c +@@ -122,6 +122,7 @@ + + 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)); +@@ -1323,6 +1324,134 @@ + 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 @@ + + #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 @@ + /* Replace first {} with archive name. If no {} append name to string. */ + here = strstr(unzip_path, "{}"); + +- 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 @@ + 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,15 +1605,12 @@ + 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 + /* Convert success severity to 0, others to non-zero. */ diff -Nru zip-3.0/debian/patches/series zip-3.0/debian/patches/series --- zip-3.0/debian/patches/series 2025-04-25 19:00:00.000000000 +0000 +++ zip-3.0/debian/patches/series 2026-08-10 22:20:00.000000000 +0000 @@ -14,3 +14,4 @@ 14-buffer-overflow-unicode-filename.patch 15-buffer-overflow-cve-2018-13410.patch 16-fix-symlink-update-detection.patch +fix-command-injection.patch