summaryrefslogtreecommitdiffstats
path: root/decompress_lunzip.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 14:27:35 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-04 14:27:35 +0000
commit78f0e21e4be26a0792535ede952c5836d66d1965 (patch)
tree4d43dd4ea1e336065ba7208e974f29afe542b7d2 /decompress_lunzip.c
parentInitial commit. (diff)
downloadxlunzip-78f0e21e4be26a0792535ede952c5836d66d1965.tar.xz
xlunzip-78f0e21e4be26a0792535ede952c5836d66d1965.zip
Adding upstream version 0.7.upstream/0.7upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'decompress_lunzip.c')
-rw-r--r--decompress_lunzip.c100
1 files changed, 100 insertions, 0 deletions
diff --git a/decompress_lunzip.c b/decompress_lunzip.c
new file mode 100644
index 0000000..9586bb5
--- /dev/null
+++ b/decompress_lunzip.c
@@ -0,0 +1,100 @@
+/*
+ * Wrapper for decompressing LZIP-compressed kernel, initramfs, and initrd
+ *
+ * Copyright (C) 2016-2021 Antonio Diaz Diaz.
+ *
+ * Licensed under GPLv2 or later, see file LICENSE in this source tree.
+ */
+
+#ifdef STATIC
+#define PREBOOT
+#include "lzip_decompress.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 include/linux/decompress/generic.h) should have an
+ * out_size argument to prevent overflowing 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