Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Step:15
gzip
bsc1198062.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File bsc1198062.patch of Package gzip
From 53f56145cc4fc9f14060c0a022f502c210d175a7 Mon Sep 17 00:00:00 2001 From: Lasse Collin <lasse.collin@tukaani.org> Date: Mon, 28 Mar 2022 09:35:27 -0700 Subject: [PATCH 1/6] zgrep: avoid exploit via multi-newline file names * 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 | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/zgrep.in b/zgrep.in index 345dae3..bdf7da2 100644 --- a/zgrep.in +++ b/zgrep.in @@ -222,9 +222,13 @@ do '* | *'&'* | *'\'* | *'|'*) i=$(printf '%s\n' "$i" | sed ' - $!N - $s/[&\|]/\\&/g - $s/\n/\\n/g + :start + $!{ + N + b start + } + s/[&\|]/\\&/g + s/\n/\\n/g ');; esac sed_script="s|^|$i:|" -- 2.35.1.677.gabf474a5dd From 9973b95d1ea12c3372805074f152bec66d81a9b4 Mon Sep 17 00:00:00 2001 From: Jim Meyering <meyering@fb.com> Date: Mon, 28 Mar 2022 09:35:27 -0700 Subject: [PATCH 2/6] zgrep: add NEWS and tests for this exploitable bug * tests/zgrep-abuse: New file, based on PoC by cleemy desu wayo. * tests/Makefile.am (TESTS): Add it. * NEWS: Mention the exploit. The bug appears to have been present since the beginning. --- NEWS | 3 +++ tests/Makefile.am | 1 + tests/zgrep-abuse | 43 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 47 insertions(+) create mode 100755 tests/zgrep-abuse diff --git a/tests/Makefile.am b/tests/Makefile.am index d09672e..5f148d6 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -36,6 +36,7 @@ TESTS = \ z-suffix \ zdiff \ zgrep-f \ + zgrep-abuse \ zgrep-context \ zgrep-signal \ znew-k diff --git a/tests/zgrep-abuse b/tests/zgrep-abuse new file mode 100755 index 0000000..f1d6699 --- /dev/null +++ b/tests/zgrep-abuse @@ -0,0 +1,43 @@ +#!/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 <https://www.gnu.org/licenses/>. +# limit so don't run it by default. + +. "${srcdir=.}/init.sh"; path_prepend_ .. + +f=z +echo test > $f || framework_failure_ +gzip $f || framework_failure_ +cp $f.gz 'zfile_crafted| +p +1s|.*|hacked1| +1w hacked +etouch .\x2fhacked2 +d +# +#' || framework_failure_ + +fail=0 + +zgrep test z* + +# Before, each of these would be created. +test -f hacked && fail=1 +test -f hacked2 && fail=1 + +Exit $fail -- 2.35.1.677.gabf474a5dd From 7801e55ae389b24dfda1d29bf7cadb434472c8dd Mon Sep 17 00:00:00 2001 From: Paul Eggert <eggert@cs.ucla.edu> Date: Mon, 28 Mar 2022 09:35:27 -0700 Subject: [PATCH 3/6] zgrep: port to POSIX sed MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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. --- zgrep.in | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/zgrep.in b/zgrep.in index bdf7da2..6a16dd1 100644 --- a/zgrep.in +++ b/zgrep.in @@ -220,18 +220,11 @@ do case $i in (*' '* | *'&'* | *'\'* | *'|'*) - i=$(printf '%s\n' "$i" | - sed ' - :start - $!{ - N - b start - } - s/[&\|]/\\&/g - s/\n/\\n/g - ');; + icolon=$(printf '%s\n' "$i:" | + sed -e 's/[&\|]/\\&/g' -e '$!s/$/\\/');; + (*) icolon="$i:";; esac - sed_script="s|^|$i:|" + sed_script="s|^|$icolon|" # Fail if grep or sed fails. r=$( -- 2.35.1.677.gabf474a5dd From ce2bf56a5e3e1814c08513c2d4141a50041e1ae4 Mon Sep 17 00:00:00 2001 From: Paul Eggert <eggert@cs.ucla.edu> Date: Mon, 28 Mar 2022 09:35:27 -0700 Subject: [PATCH 4/6] gzip: mention when fixed bugs were introduced --- NEWS | 2 ++ 1 file changed, 2 insertions(+) -- 2.35.1.677.gabf474a5dd From 42641236d0bb239768794eec93a86c42cbfc2f6a Mon Sep 17 00:00:00 2001 From: Paul Eggert <eggert@cs.ucla.edu> Date: Mon, 28 Mar 2022 09:35:27 -0700 Subject: [PATCH 5/6] gzexe: optimize out a grep MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 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 | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/gzexe.in b/gzexe.in index 04b06a9..1a691e0 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 `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" -- 2.35.1.677.gabf474a5dd From 526466454cef8dbfcf552e16a171a44f181c8ca0 Mon Sep 17 00:00:00 2001 From: Paul Eggert <eggert@cs.ucla.edu> Date: Mon, 28 Mar 2022 09:35:27 -0700 Subject: [PATCH 6/6] maint: use C locale more often * 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. --- gzexe.in | 4 ++-- sample/zfile | 3 +++ zdiff.in | 4 ++-- zgrep.in | 29 +++++++++++++++++------------ znew.in | 3 +++ 5 files changed, 27 insertions(+), 16 deletions(-) diff --git a/gzexe.in b/gzexe.in index 1a691e0..5fc7204 100644 --- a/gzexe.in +++ b/gzexe.in @@ -91,7 +91,7 @@ for i do continue fi if test $decomp -eq 0; then - case `sed -n -e 1d -e '/^skip=[0-9][0-9]*$/p' -e 2q "$file"` in + 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;; @@ -203,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/zdiff.in b/zdiff.in index 012024e..eb4752b 100644 --- a/zdiff.in +++ b/zdiff.in @@ -59,7 +59,7 @@ 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 @@ -103,7 +103,7 @@ case $file2 in 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 6a16dd1..2cb2426 100644 --- a/zgrep.in +++ b/zgrep.in @@ -64,30 +64,33 @@ 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 +99,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,7 +173,7 @@ 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 @@ -182,7 +186,7 @@ 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");; + grep="$grep -- '"$(printf '%s\n' "$1" | LC_ALL=C sed "$escape");; (*) grep="$grep -- '$1'";; esac @@ -221,7 +225,7 @@ do (*' '* | *'&'* | *'\'* | *'|'*) icolon=$(printf '%s\n' "$i:" | - sed -e 's/[&\|]/\\&/g' -e '$!s/$/\\/');; + LC_ALL=C sed -e 's/[&\|]/\\&/g' -e '$!s/$/\\/');; (*) icolon="$i:";; esac sed_script="s|^|$icolon|" @@ -229,7 +233,8 @@ do # Fail if grep or sed fails. r=$( exec 4>&1 - (eval "$grep" 4>&-; echo $? >&4) 3>&- | sed "$sed_script" >&3 4>&- + (eval "$grep" 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 45d0764..ea76a22 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 -- 2.35.1.677.gabf474a5dd
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor