lzma/gzip: fix potential oops when input data is truncated
authorPhillip Lougher <phillip@lougher.demon.co.uk>
Wed, 23 Sep 2009 22:57:37 +0000 (15:57 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Thu, 24 Sep 2009 14:21:05 +0000 (07:21 -0700)
If the lzma/gzip decompressors are called with insufficient input data
(len > 0 & fill = NULL), they will attempt to call the fill function to
obtain more data, leading to a kernel oops.

Signed-off-by: Phillip Lougher <phillip@lougher.demon.co.uk>
Cc: "H. Peter Anvin" <hpa@zytor.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
lib/decompress_inflate.c
lib/decompress_unlzma.c

index 68dfce59c1b80be510544c0effc3f87669527b8f..fc686c7a0a0da688dd9dee52156dc7f6c0c380ab 100644 (file)
 
 #define GZIP_IOBUF_SIZE (16*1024)
 
+static int nofill(void *buffer, unsigned int len)
+{
+       return -1;
+}
+
 /* Included from initramfs et al code */
 STATIC int INIT gunzip(unsigned char *buf, int len,
                       int(*fill)(void*, unsigned int),
@@ -76,6 +81,9 @@ STATIC int INIT gunzip(unsigned char *buf, int len,
                goto gunzip_nomem4;
        }
 
+       if (!fill)
+               fill = nofill;
+
        if (len == 0)
                len = fill(zbuf, GZIP_IOBUF_SIZE);
 
index 0b954e04bd3015bb08332b2a30a13e1ff6414fea..ca82fde81c8fc48a39a22495fbe9d489142d04aa 100644 (file)
@@ -82,6 +82,11 @@ struct rc {
 #define RC_MODEL_TOTAL_BITS 11
 
 
+static int nofill(void *buffer, unsigned int len)
+{
+       return -1;
+}
+
 /* Called twice: once at startup and once in rc_normalize() */
 static void INIT rc_read(struct rc *rc)
 {
@@ -97,7 +102,10 @@ static inline void INIT rc_init(struct rc *rc,
                                       int (*fill)(void*, unsigned int),
                                       char *buffer, int buffer_size)
 {
-       rc->fill = fill;
+       if (fill)
+               rc->fill = fill;
+       else
+               rc->fill = nofill;
        rc->buffer = (uint8_t *)buffer;
        rc->buffer_size = buffer_size;
        rc->buffer_end = rc->buffer + rc->buffer_size;