Commit 6a8811629e9aa611aa710162f9e02020bba52c87
Committed by
Linus Torvalds
1 parent
3354f73b24
Exists in
master
and in
4 other branches
lzma/gzip: fix potential oops when input data is truncated
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>
Showing 2 changed files with 17 additions and 1 deletions Side-by-side Diff
lib/decompress_inflate.c
... | ... | @@ -27,6 +27,11 @@ |
27 | 27 | |
28 | 28 | #define GZIP_IOBUF_SIZE (16*1024) |
29 | 29 | |
30 | +static int nofill(void *buffer, unsigned int len) | |
31 | +{ | |
32 | + return -1; | |
33 | +} | |
34 | + | |
30 | 35 | /* Included from initramfs et al code */ |
31 | 36 | STATIC int INIT gunzip(unsigned char *buf, int len, |
32 | 37 | int(*fill)(void*, unsigned int), |
... | ... | @@ -75,6 +80,9 @@ |
75 | 80 | error("Out of memory while allocating workspace"); |
76 | 81 | goto gunzip_nomem4; |
77 | 82 | } |
83 | + | |
84 | + if (!fill) | |
85 | + fill = nofill; | |
78 | 86 | |
79 | 87 | if (len == 0) |
80 | 88 | len = fill(zbuf, GZIP_IOBUF_SIZE); |
lib/decompress_unlzma.c
... | ... | @@ -82,6 +82,11 @@ |
82 | 82 | #define RC_MODEL_TOTAL_BITS 11 |
83 | 83 | |
84 | 84 | |
85 | +static int nofill(void *buffer, unsigned int len) | |
86 | +{ | |
87 | + return -1; | |
88 | +} | |
89 | + | |
85 | 90 | /* Called twice: once at startup and once in rc_normalize() */ |
86 | 91 | static void INIT rc_read(struct rc *rc) |
87 | 92 | { |
... | ... | @@ -97,7 +102,10 @@ |
97 | 102 | int (*fill)(void*, unsigned int), |
98 | 103 | char *buffer, int buffer_size) |
99 | 104 | { |
100 | - rc->fill = fill; | |
105 | + if (fill) | |
106 | + rc->fill = fill; | |
107 | + else | |
108 | + rc->fill = nofill; | |
101 | 109 | rc->buffer = (uint8_t *)buffer; |
102 | 110 | rc->buffer_size = buffer_size; |
103 | 111 | rc->buffer_end = rc->buffer + rc->buffer_size; |