diff options
Diffstat (limited to 'decompress_lunzip.c')
-rw-r--r-- | decompress_lunzip.c | 100 |
1 files changed, 100 insertions, 0 deletions
diff --git a/decompress_lunzip.c b/decompress_lunzip.c new file mode 100644 index 0000000..106c95b --- /dev/null +++ b/decompress_lunzip.c @@ -0,0 +1,100 @@ +/* + * Wrapper for decompressing LZIP-compressed kernel, initramfs, and initrd + * + * Copyright (C) 2016-2018 Antonio Diaz Diaz. + * + * Licensed under GPLv2 or later, see file LICENSE in this source tree. + */ + +#ifdef STATIC +#define PREBOOT +#include "lzip.c" +#else +#include "linux_lzip.h" +#include "linux_lunzip.h" +#include "linux_mm.h" +#endif + +STATIC int INIT __lunzip(unsigned char *inbuf, long in_len, + long (*fill)(void*, unsigned long), + long (*flush)(void*, unsigned long), + unsigned char *outbuf, long out_size, + long *in_posp, long *out_posp, + void (*error)(char *x)) +{ + const int retval = lzip_decompress(inbuf, in_len, fill, flush, + outbuf, out_size, in_posp, out_posp); + switch (retval) { + case 0: break; + case LZIP_OOM_INBUF: + error("Out of memory while allocating input buffer."); + break; + case LZIP_HEADER1_EOF: + error("File ends unexpectedly at member header."); + break; + case LZIP_HEADER2_EOF: + error("Truncated header in multimember file."); + break; + case LZIP_BAD_MAGIC1: + error("Bad magic number (file not in lzip format)."); + break; + case LZIP_BAD_MAGIC2: + error("Corrupt header in multimember file."); + break; + case LZIP_BAD_VERSION: + error("Version of lzip member format not supported."); + break; + case LZIP_BAD_DICT_SIZE: + error("Invalid dictionary size in member header."); + break; + case LZIP_OOM_OUTBUF: + error("Out of memory while allocating output buffer."); + break; + case LZIP_WRITE_ERROR: + error("Write error."); + break; + case LZIP_BAD_DATA: + error("LZIP-compressed data is corrupt."); + break; + case LZIP_DATA_EOF: + error("LZIP-compressed data ends unexpectedly."); + break; + case LZIP_BAD_CRC: + error("CRC mismatch in LZIP-compressed data."); + break; + default: + error("Bug in the LZIP decompressor."); + } + return retval; +} + +#ifndef PREBOOT +/* decompress_fn (see linux/decompress/generic.h) should have an out_size + * argument to prevent overrunning outbuf in case of corruption of the + * compressed data. + */ +STATIC int INIT lunzip(unsigned char *inbuf, long in_len, + long (*fill)(void*, unsigned long), + long (*flush)(void*, unsigned long), + unsigned char *outbuf, + long *in_posp, + void (*error)(char *x)) +{ + return __lunzip(inbuf, in_len, fill, flush, outbuf, LONG_MAX, + in_posp, 0, error); +} +#else +STATIC int INIT __decompress(unsigned char *inbuf, long in_len, + long (*fill)(void*, unsigned long), + long (*flush)(void*, unsigned long), + unsigned char *outbuf, long out_size, + long *in_posp, + void (*error)(char *x)) +{ +/* Some archs pass out_size = 0 (to mean unlimited size), which is unsafe + * in case of corruption of the compressed data. + */ + return __lunzip(inbuf, in_len - 4, fill, flush, outbuf, + out_size ? out_size : LONG_MAX, in_posp, 0, error); +} +#endif |