summaryrefslogtreecommitdiffstats
path: root/lib/decompress_unlzo.c
diff options
context:
space:
mode:
authorYinghai Lu <yinghai@kernel.org>2015-09-09 18:39:12 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2015-09-10 16:29:01 -0400
commit2d3862d26e67a59340ba1cf1748196c76c5787de (patch)
treee3b1dd9157a0c745bcd8147cad82bf021a1cec72 /lib/decompress_unlzo.c
parente852d82a5b55b44ce8be89078d0dfbddbeae3211 (diff)
lib/decompressors: use real out buf size for gunzip with kernel
When loading x86 64bit kernel above 4GiB with patched grub2, got kernel gunzip error. | early console in decompress_kernel | decompress_kernel: | input: [0x807f2143b4-0x807ff61aee] | output: [0x807cc00000-0x807f3ea29b] 0x027ea29c: output_len | boot via startup_64 | KASLR using RDTSC... | new output: [0x46fe000000-0x470138cfff] 0x0338d000: output_run_size | decompress: [0x46fe000000-0x47007ea29b] <=== [0x807f2143b4-0x807ff61aee] | | Decompressing Linux... gz... | | uncompression error | | -- System halted the new buffer is at 0x46fe000000ULL, decompressor_gzip is using 0xffffffb901ffffff as out_len. gunzip in lib/zlib_inflate/inflate.c cap that len to 0x01ffffff and decompress fails later. We could hit this problem with crashkernel booting that uses kexec loading kernel above 4GiB. We have decompress_* support: 1. inbuf[]/outbuf[] for kernel preboot. 2. inbuf[]/flush() for initramfs 3. fill()/flush() for initrd. This bug only affect kernel preboot path that use outbuf[]. Add __decompress and take real out_buf_len for gunzip instead of guessing wrong buf size. Fixes: 1431574a1c4 (lib/decompressors: fix "no limit" output buffer length) Signed-off-by: Yinghai Lu <yinghai@kernel.org> Cc: Alexandre Courbot <acourbot@nvidia.com> Cc: Jon Medhurst <tixy@linaro.org> Cc: Stephen Warren <swarren@wwwdotorg.org> Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: Thomas Gleixner <tglx@linutronix.de> Cc: Ingo Molnar <mingo@redhat.com> Cc: <stable@vger.kernel.org> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'lib/decompress_unlzo.c')
-rw-r--r--lib/decompress_unlzo.c13
1 files changed, 12 insertions, 1 deletions
diff --git a/lib/decompress_unlzo.c b/lib/decompress_unlzo.c
index b94a31bdd87d..f4c158e3a022 100644
--- a/lib/decompress_unlzo.c
+++ b/lib/decompress_unlzo.c
@@ -31,6 +31,7 @@
31 */ 31 */
32 32
33#ifdef STATIC 33#ifdef STATIC
34#define PREBOOT
34#include "lzo/lzo1x_decompress_safe.c" 35#include "lzo/lzo1x_decompress_safe.c"
35#else 36#else
36#include <linux/decompress/unlzo.h> 37#include <linux/decompress/unlzo.h>
@@ -287,4 +288,14 @@ exit:
287 return ret; 288 return ret;
288} 289}
289 290
290#define decompress unlzo 291#ifdef PREBOOT
292STATIC int INIT __decompress(unsigned char *buf, long len,
293 long (*fill)(void*, unsigned long),
294 long (*flush)(void*, unsigned long),
295 unsigned char *out_buf, long olen,
296 long *pos,
297 void (*error)(char *x))
298{
299 return unlzo(buf, len, fill, flush, out_buf, pos, error);
300}
301#endif