Version in base suite: 1.10-4 Base version: gzip_1.10-4 Target version: gzip_1.10-4+deb11u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/g/gzip/gzip_1.10-4.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/g/gzip/gzip_1.10-4+deb11u1.dsc changelog | 7 patches/CVE-2022-1271.patch | 383 ++++++++++++++++++++++++++++++++++++++++++++ patches/series | 1 3 files changed, 391 insertions(+) diff -Nru gzip-1.10/debian/changelog gzip-1.10/debian/changelog --- gzip-1.10/debian/changelog 2021-03-02 23:30:16.000000000 +0000 +++ gzip-1.10/debian/changelog 2022-04-10 05:50:32.000000000 +0000 @@ -1,3 +1,10 @@ +gzip (1.10-4+deb11u1) bullseye-security; urgency=high + + * zgrep: fix arbitrary-file-write vulnerability + addressing CVE-2022-1271 (closes: #1009168) + + -- Milan Kupcevic Sun, 10 Apr 2022 01:50:32 -0400 + gzip (1.10-4) sid; urgency=medium * skip out of range timestamp test on mips64el (closes: #983706) diff -Nru gzip-1.10/debian/patches/CVE-2022-1271.patch gzip-1.10/debian/patches/CVE-2022-1271.patch --- gzip-1.10/debian/patches/CVE-2022-1271.patch 1970-01-01 00:00:00.000000000 +0000 +++ gzip-1.10/debian/patches/CVE-2022-1271.patch 2022-04-10 05:50:32.000000000 +0000 @@ -0,0 +1,383 @@ +Description: fix arbitrary-file-write vulnerability (CVE-2022-1271) + Backported from gzip version 1.12: + . + * zgrep.in: The issue with the old code is that with multiple + newlines, the N-command will read the second line of input, + then the s-commands will be skipped because it's not the end + of the file yet, then a new sed cycle starts and the pattern + space is printed and emptied. So only the last line or two get + escaped. This patch makes sed read all lines into the pattern + space and then do the escaping. + . + This vulnerability was discovered by: + cleemy desu wayo working with Trend Micro Zero Day Initiative + . + * zgrep.in (res): When escaping the file name do not rely on GNU + sed’s extension to POSIX with respect to s/.../\n/. Instead, use + features that should also work with AIX and/or Solaris sed. This is + simpler anyway, and would have prevented the recently-fixed bug. + . + * gzexe.in: Avoid an unnecessary invocation of ‘grep’, + by using sed instead. Also, look only for at-most-3-digit numbers, + for consistency with the rest of the script. + . + * gzexe.in, zdiff.in, zgrep.in: + Run expr and sed in the C locale when it might help to avoid + undefined behavior on non-GNU platforms. + . + * sample/zfile, znew.in: Run in the C locale, for simplicity and + to avoid undefined behavior on non-GNU platforms. + . + Problem reported by Jim Avera (Bug#31280). + This became more of an issue when GNU grep 3.5 (2020) started sending + "binary file matches" diagnostics to stderr instead of to stdout. + . + * tests/Makefile.am (TESTS): Add zgrep-binary. + . + * tests/zgrep-binary: New test. + . + * zgrep.in (args): New var, to accumulate args separately + from grep command, so we can prepend args if need be. + Most uses of 'grep' changed to use 'args' instead, or also. + (with_filename): Set to 1 if more than one file and -h not given; + this simplifies later code. + (gnuish_grep): New var; evaluates to true if grep supports + -H and --label options, as is true for GNU and FreeBSD grep. + Append -H to 'grep' if outputting file names with GNUish grep, + and use --label with GNUish grep unless reading from stdin, + as that’s safer and more efficient than relabeling with 'sed'. + +Origin: backport, + https://git.savannah.gnu.org/cgit/gzip.git/commit/?id=dc9740df61e575e8c3148b7bd3c147a81ea00c7c + https://git.savannah.gnu.org/cgit/gzip.git/commit/?id=d74a30d45c6834c8e9f87115197370fe86656d81 + https://git.savannah.gnu.org/cgit/gzip.git/commit/?id=c99f320d5c0fd98fe88d9cea5407eb7ad9d50e8a + https://git.savannah.gnu.org/cgit/gzip.git/commit/?id=6543c09c6ecfb1630085d440b76511953bc5a2cb + https://git.savannah.gnu.org/cgit/gzip.git/commit/?id=0e2d07fc2c4393cfb9dbab580d0bee4525b9c9b3 + https://git.savannah.gnu.org/cgit/gzip.git/commit/?id=5e1fc8b92c1af9382365aef0f9130341ee1d2c76 + https://git.savannah.gnu.org/cgit/gzip.git/commit/?id=9d3248751178939713a39115cf68ec8a11506cc9 + +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +diff --git a/gzexe.in b/gzexe.in +index 3076b68..ee8a9f5 100644 +--- a/gzexe.in ++++ b/gzexe.in +@@ -91,10 +91,11 @@ for i do + continue + fi + if test $decomp -eq 0; then +- if sed -e 1d -e 2q "$file" | grep "^skip=[0-9][0-9]*$" >/dev/null; then ++ case `LC_ALL=C sed -n -e 1d -e '/^skip=[0-9][0-9]*$/p' -e 2q "$file"` in ++ skip=[0-9] | skip=[0-9][0-9] | skip=[0-9][0-9][0-9]) + printf >&2 '%s\n' "$0: $i is already gzexe'd" +- continue +- fi ++ continue;; ++ esac + fi + if test -u "$file"; then + printf >&2 '%s\n' "$0: $i has setuid permission, unchanged" +@@ -202,7 +203,7 @@ EOF + else + # decompression + skip=44 +- skip_line=`sed -e 1d -e 2q "$file"` ++ skip_line=`LC_ALL=C sed -e 1d -e 2q "$file"` + case $skip_line in + skip=[0-9] | skip=[0-9][0-9] | skip=[0-9][0-9][0-9]) + eval "$skip_line";; +diff --git a/sample/zfile b/sample/zfile +index 6b4514c..d6e7a59 100755 +--- a/sample/zfile ++++ b/sample/zfile +@@ -1,5 +1,8 @@ + #!/bin/sh + ++LC_ALL=C ++export LC_ALL ++ + if test $# = 0; then + echo 'zfile: file(1) for programs which may be compressed with gzexe' + echo usage: `basename $0` files... +diff --git a/tests/Makefile.am b/tests/Makefile.am +index 691bbf8..1e6b05b 100644 +--- a/tests/Makefile.am ++++ b/tests/Makefile.am +@@ -34,6 +34,8 @@ TESTS = \ + z-suffix \ + zdiff \ + zgrep-f \ ++ zgrep-abuse \ ++ zgrep-binary \ + zgrep-context \ + zgrep-signal \ + znew-k +diff --git a/tests/zgrep-abuse b/tests/zgrep-abuse +new file mode 100755 +index 0000000..3e8a8f9 +--- /dev/null ++++ b/tests/zgrep-abuse +@@ -0,0 +1,41 @@ ++#!/bin/sh ++# Show how zgrep applied to a crafted file name may overwrite ++# a selected file with chosen content. Fixed in gzip-1.12. ++ ++# Copyright (C) 2022 Free Software Foundation, Inc. ++ ++# This program is free software: you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++# limit so don't run it by default. ++ ++. "${srcdir=.}/init.sh"; path_prepend_ .. ++ ++: > z || framework_failure_ ++echo test |gzip > 'z| ++p ++1s|.*|chosen-content| ++1w hacked ++etouch .\x2fhacked2 ++d ++# ++#' || framework_failure_ ++ ++fail=0 ++ ++zgrep test z* > /dev/null ++ ++# Before the fix, each of these would be created. ++test -f hacked && fail=1 ++test -f hacked2 && fail=1 ++ ++Exit $fail +diff --git a/tests/zgrep-binary b/tests/zgrep-binary +new file mode 100755 +index 0000000..6c00cef +--- /dev/null ++++ b/tests/zgrep-binary +@@ -0,0 +1,30 @@ ++#!/bin/sh ++# 'zgrep PATTERN FILE' would output "(standard input): binary file matches" ++# without mentioning FILE. Fixed in gzip-1.12. ++ ++# Copyright (C) 2022 Free Software Foundation, Inc. ++ ++# This program is free software: you can redistribute it and/or modify ++# it under the terms of the GNU General Public License as published by ++# the Free Software Foundation, either version 3 of the License, or ++# (at your option) any later version. ++ ++# This program is distributed in the hope that it will be useful, ++# but WITHOUT ANY WARRANTY; without even the implied warranty of ++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++# GNU General Public License for more details. ++ ++# You should have received a copy of the GNU General Public License ++# along with this program. If not, see . ++# limit so don't run it by default. ++ ++. "${srcdir=.}/init.sh"; path_prepend_ .. ++ ++fail=0 ++ ++unset GREP_OPTIONS ++ ++printf 'foo\0\n' >f || framework_failure_ ++LC_ALL=C zgrep foo f >out 2>err && grep '(standard input)' out err && fail=1 ++ ++Exit $fail +diff --git a/zdiff.in b/zdiff.in +index 4cf7395..e8df1ec 100644 +--- a/zdiff.in ++++ b/zdiff.in +@@ -53,7 +53,7 @@ while :; do + --h*) printf '%s\n' "$usage" || exit 2; exit;; + --v*) printf '%s\n' "$version" || exit 2; exit;; + --) shift; break;; +- -*\'*) cmp="$cmp '"`printf '%sX\n' "$1" | sed "$escape"`;; ++ -*\'*) cmp="$cmp '"`printf '%sX\n' "$1" | LC_ALL=C sed "$escape"`;; + -?*) cmp="$cmp '$1'";; + *) break;; + esac +@@ -72,7 +72,7 @@ exec 3>&1 + if test $# -eq 1; then + case $1 in + *[-.]gz* | *[-.][zZ] | *.t[ga]z) +- FILE=`expr "X$1" : 'X\(.*\)[-.][zZtga]*$'` ++ FILE=`LC_ALL=C expr "X$1" : 'X\(.*\)[-.][zZtga]*$'` + gzip_status=$( + exec 4>&1 + (gzip -cd -- "$1" 4>&-; echo $? >&4) 3>&- | eval "$cmp" - '"$FILE"' >&3 +diff --git a/zgrep.in b/zgrep.in +index 3efdb52..d1bd56b 100644 +--- a/zgrep.in ++++ b/zgrep.in +@@ -23,6 +23,7 @@ + # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + + grep='${GREP-'\''@GREP@'\''}' ++args= + + version='zgrep (gzip) @VERSION@ + Copyright (C) 2010-2018 Free Software Foundation, Inc. +@@ -64,30 +65,30 @@ while test $# -ne 0; do + + case $option in + (-[0123456789EFGHIKLPRTUVZabchilnoqrsuvwxyz]*[!0123456789]*) +- arg2=-\'$(expr "X$option" : 'X-.[0-9]*\(.*\)' | sed "$escape") ++ arg2=-\'$(LC_ALL=C expr "X$option" : 'X-.[0-9]*\(.*\)' | LC_ALL=C sed "$escape") + eval "set -- $arg2 "'${1+"$@"}' +- option=$(expr "X$option" : 'X\(-.[0-9]*\)');; ++ option=$(LC_ALL=C expr "X$option" : 'X\(-.[0-9]*\)');; + (--binary-*=* | --[lm]a*=* | --reg*=*) + ;; + (-[ABCDXdefm] | --binary-* | --file | --[lm]a* | --reg*) + case ${1?"$option option requires an argument"} in + (*\'*) +- optarg=" '"$(printf '%s\n' "$1" | sed "$escape");; ++ optarg=" '"$(printf '%s\n' "$1" | LC_ALL=C sed "$escape");; + (*) + optarg=" '$1'";; + esac + shift;; + (-f?*\'*) +- optarg=" '"$(expr "X$option" : 'X-f\(.*\)' | sed "$escape") ++ optarg=" '"$(LC_ALL=C expr "X$option" : 'X-f\(.*\)' | LC_ALL=C sed "$escape") + option=-f;; + (-f?*) +- optarg=" '"$(expr "X$option" : 'X-f\(.*\)')\' ++ optarg=" '"$(LC_ALL=C expr "X$option" : 'X-f\(.*\)')\' + option=-f;; + (--file=*\'*) +- optarg=" '"$(expr "X$option" : 'X--file=\(.*\)' | sed "$escape") ++ optarg=" '"$(LC_ALL=C expr "X$option" : 'X--file=\(.*\)' | LC_ALL=C sed "$escape") + option=--file;; + (--file=*) +- optarg=" '"$(expr "X$option" : 'X--file=\(.*\)')\' ++ optarg=" '"$(LC_ALL=C expr "X$option" : 'X--file=\(.*\)')\' + option=--file;; + (--) + break;; +@@ -96,7 +97,8 @@ while test $# -ne 0; do + (*) + case $option in + (*\'*) +- operands="$operands '"$(printf '%s\n' "$option" | sed "$escape");; ++ operands="$operands '"$(printf '%s\n' "$option" | LC_ALL=C sed "$escape") ++ ;; + (*) + operands="$operands '$option'";; + esac +@@ -169,12 +171,12 @@ while test $# -ne 0; do + + case $option in + (*\'?*) +- option=\'$(printf '%s\n' "$option" | sed "$escape");; ++ option=\'$(printf '%s\n' "$option" | LC_ALL=C sed "$escape");; + (*) + option="'$option'";; + esac + +- grep="$grep $option$optarg" ++ args="$args $option$optarg" + done + + eval "set -- $operands "'${1+"$@"}' +@@ -182,15 +184,23 @@ eval "set -- $operands "'${1+"$@"}' + if test $have_pat -eq 0; then + case ${1?"missing pattern; try \`$0 --help' for help"} in + (*\'*) +- grep="$grep -- '"$(printf '%s\n' "$1" | sed "$escape");; ++ args="$args -- '"$(printf '%s\n' "$1" | LC_ALL=C sed "$escape");; + (*) +- grep="$grep -- '$1'";; ++ args="$args -- '$1'";; + esac + shift + fi + + if test $# -eq 0; then + set -- - ++elif test 1 -lt $# && test $no_filename -eq 0; then ++ with_filename=1 ++fi ++ ++l_e=$(eval "(echo e | $grep -H --label=l e) 2>/dev/null") && test "$l_e" = l:e ++gnuish_grep="test $? -eq 0" ++if $gnuish_grep && test $with_filename -eq 1; then ++ grep="$grep -H" + fi + + exec 3>&1 +@@ -203,9 +213,9 @@ do + exec 5>&1 + (gzip -cdfq -- "$i" 5>&-; echo $? >&5) 3>&- | + if test $files_with_matches -eq 1; then +- eval "$grep" >/dev/null && { printf '%s\n' "$i" || exit 2; } ++ eval "$grep$args" >/dev/null && { printf '%s\n' "$i" || exit 2; } + elif test $files_without_matches -eq 1; then +- eval "$grep" >/dev/null || { ++ eval "$grep$args" >/dev/null || { + r=$? + if test $r -eq 1; then + printf '%s\n' "$i" || r=2 +@@ -213,26 +223,25 @@ do + test 256 -le $r && r=$(expr 128 + $r % 128) + exit $r + } +- elif test $with_filename -eq 0 && +- { test $# -eq 1 || test $no_filename -eq 1; }; then +- eval "$grep" ++ elif $gnuish_grep && test "$i" != -; then ++ eval "$grep --label \"\$i\"$args" ++ elif $gnuish_grep || test $with_filename -eq 0; then ++ eval "$grep$args" + else + case $i in + (*' + '* | *'&'* | *'\'* | *'|'*) +- i=$(printf '%s\n' "$i" | +- sed ' +- $!N +- $s/[&\|]/\\&/g +- $s/\n/\\n/g +- ');; ++ icolon=$(printf '%s\n' "$i:" | ++ LC_ALL=C sed -e 's/[&\|]/\\&/g' -e '$!s/$/\\/');; ++ (*) icolon="$i:";; + esac +- sed_script="s|^|$i:|" ++ sed_script="s|^|$icolon|" + + # Fail if grep or sed fails. + r=$( + exec 4>&1 +- (eval "$grep" 4>&-; echo $? >&4) 3>&- | sed "$sed_script" >&3 4>&- ++ (eval "$grep$args" 4>&-; echo $? >&4) 3>&- | ++ LC_ALL=C sed "$sed_script" >&3 4>&- + ) || { r=$?; test $r -lt 2 && r=2; } + test 256 -le $r && r=$(expr 128 + $r % 128) + exit $r +diff --git a/znew.in b/znew.in +index 2b703d1..0cf1909 100644 +--- a/znew.in ++++ b/znew.in +@@ -18,6 +18,9 @@ + # with this program; if not, write to the Free Software Foundation, Inc., + # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + ++LC_ALL=C ++export LC_ALL ++ + version="znew (gzip) @VERSION@ + Copyright (C) 2010-2018 Free Software Foundation, Inc. + This is free software. You may redistribute copies of it under the terms of diff -Nru gzip-1.10/debian/patches/series gzip-1.10/debian/patches/series --- gzip-1.10/debian/patches/series 2021-03-02 22:49:35.000000000 +0000 +++ gzip-1.10/debian/patches/series 2022-04-10 05:50:32.000000000 +0000 @@ -4,3 +4,4 @@ disable-Werror.patch gzexe-fix-count-of-lines-to-skip.patch skip-out-of-range-timestamp-test-mips64el.patch +CVE-2022-1271.patch