Here's the patch for CVE-2010-0001, along with a test to exercise the offending code.
I expect to release gzip-1.4 within the next few hours. >From a3db5806d012082b9e25cc36d09f19cd736a468f Mon Sep 17 00:00:00 2001 From: Jim Meyering <[email protected]> Date: Sun, 10 Jan 2010 17:13:01 +0100 Subject: [PATCH 1/2] gzip -d: do not clobber stack for valid input on x86_64 * unlzw.c (unlzw): Avoid integer overflow. Aki Helin reported the segfault along with an input to trigger the bug. * NEWS (Bug fixes): Mention it. --- NEWS | 5 +++++ THANKS | 1 + unlzw.c | 3 ++- 3 files changed, 8 insertions(+), 1 deletions(-) diff --git a/NEWS b/NEWS index 3e50762..747253f 100644 --- a/NEWS +++ b/NEWS @@ -4,6 +4,11 @@ GNU gzip NEWS -*- outline -*- ** Bug fixes + gzip -d could segfault and/or clobber the stack, possibly leading to + arbitrary code execution. This affects x86_64 but not 32-bit systems. + This fixes CVE-2010-0001. + For more details, see http://bugzilla.redhat.com/554418 + gzip -d would fail with a CRC error for some valid inputs. So far, the only valid input known to exhibit this failure was compressed "from FAT filesystem (MS-DOS, OS/2, NT)". In addition, diff --git a/THANKS b/THANKS index 4725543..183d39c 100644 --- a/THANKS +++ b/THANKS @@ -97,6 +97,7 @@ Harald Hanche-Olsen [email protected] Darrel R. Hankerson [email protected] Mark Hanning-Lee [email protected] Lars Hecking [email protected] +Aki Helin [email protected] Ruediger Helsch [email protected] Mark C. Henderson [email protected] Karl Heuer [email protected] diff --git a/unlzw.c b/unlzw.c index fb9ff76..8f8cbee 100644 --- a/unlzw.c +++ b/unlzw.c @@ -240,7 +240,8 @@ int unlzw(in, out) int o; resetbuf: - e = insize-(o = (posbits>>3)); + o = posbits >> 3; + e = o <= insize ? insize - o : 0; for (i = 0 ; i < e ; ++i) { inbuf[i] = inbuf[i+o]; -- 1.6.6.516.gb72f >From 3da56715dbc74c84b793f018a87e10992172f634 Mon Sep 17 00:00:00 2001 From: Jim Meyering <[email protected]> Date: Mon, 11 Jan 2010 08:20:52 +0100 Subject: [PATCH 2/2] tests: exercise the segfault fix * tests/helin-segv: New test. * Makefile.am (TESTS): Add it. --- Makefile.am | 1 + tests/helin-segv | 37 +++++++++++++++++++++++++++++++++++++ 2 files changed, 38 insertions(+), 0 deletions(-) create mode 100755 tests/helin-segv diff --git a/Makefile.am b/Makefile.am index 67dc18b..ac95615 100644 --- a/Makefile.am +++ b/Makefile.am @@ -104,6 +104,7 @@ check-local: $(FILES_TO_CHECK) $(bin_PROGRAMS) gzip.doc.gz @echo 'Test succeeded.' TESTS = \ + tests/helin-segv \ tests/memcpy-abuse \ tests/trailing-nul \ tests/zdiff \ diff --git a/tests/helin-segv b/tests/helin-segv new file mode 100755 index 0000000..d6b14f6 --- /dev/null +++ b/tests/helin-segv @@ -0,0 +1,37 @@ +#!/bin/sh +# Before gzip-1.4, gzip -d would segfault on some inputs. + +# Copyright (C) 2010 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 <http://www.gnu.org/licenses/>. +# limit so don't run it by default. + +if test "$VERBOSE" = yes; then + set -x + gzip --version +fi + +: ${srcdir=.} +. "$srcdir/tests/init.sh"; path_prepend_ . + +# This test case was provided by Aki Helin. +printf '\037\235\220\0\0\0\304' > helin.gz || framework_failure +printf '\0\0' > exp || framework_failure + +fail=0 + +gzip -dc helin.gz > out || fail=1 +compare out exp || fail=1 + +Exit $fail -- 1.6.6.516.gb72f
