gzip -d: do not clobber stack for valid input on x86_64
authorJim Meyering <meyering@redhat.com>
Sun, 10 Jan 2010 16:13:01 +0000 (17:13 +0100)
committerJim Meyering <meyering@redhat.com>
Wed, 20 Jan 2010 14:00:28 +0000 (15:00 +0100)
* 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
THANKS
unlzw.c

diff --git a/NEWS b/NEWS
index 3e50762ed4853287e7c1a15b1c275554fd6a3384..747253f131ae5538ee624f426509879ab1e24fb0 100644 (file)
--- 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 47255436db3b4c08cc04b2d2e19c39485131f5fa..183d39ce9f71e96594d9c1ed0496b28c8a9f3342 100644 (file)
--- a/THANKS
+++ b/THANKS
@@ -97,6 +97,7 @@ Harald Hanche-Olsen     hanche@ams.sunysb.edu
 Darrel R. Hankerson     hankedr@mail.auburn.edu
 Mark Hanning-Lee        markhl@romeo.caltech.edu
 Lars Hecking            st000002@hrz1.hrz.th-darmstadt.de
+Aki Helin               aki.helin@iki.fi
 Ruediger Helsch         ruediger@ramz.ing.tu-bs.de
 Mark C. Henderson       mch@sqwest.wimsey.bc.ca
 Karl Heuer              karl@kelp.boston.ma.us
diff --git a/unlzw.c b/unlzw.c
index fb9ff76dc92281d0fcf7c65095db3ef54aa28cb6..8f8cbeee16fa007762ae842d76e1ad1398c6066b 100644 (file)
--- 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];