aboutsummaryrefslogtreecommitdiff
path: root/lib/decompress_inflate.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/decompress_inflate.c')
-rw-r--r--lib/decompress_inflate.c40
1 files changed, 28 insertions, 12 deletions
diff --git a/lib/decompress_inflate.c b/lib/decompress_inflate.c
index e36b296fc9f..0edfd742a15 100644
--- a/lib/decompress_inflate.c
+++ b/lib/decompress_inflate.c
@@ -19,13 +19,18 @@
#include "zlib_inflate/inflate.h"
#include "zlib_inflate/infutil.h"
+#include <linux/decompress/inflate.h>
#endif /* STATIC */
#include <linux/decompress/mm.h>
-#include <linux/slab.h>
-#define INBUF_LEN (16*1024)
+#define GZIP_IOBUF_SIZE (16*1024)
+
+static int INIT nofill(void *buffer, unsigned int len)
+{
+ return -1;
+}
/* Included from initramfs et al code */
STATIC int INIT gunzip(unsigned char *buf, int len,
@@ -33,19 +38,18 @@ STATIC int INIT gunzip(unsigned char *buf, int len,
int(*flush)(void*, unsigned int),
unsigned char *out_buf,
int *pos,
- void(*error_fn)(char *x)) {
+ void(*error)(char *x)) {
u8 *zbuf;
struct z_stream_s *strm;
int rc;
size_t out_len;
- set_error_fn(error_fn);
rc = -1;
if (flush) {
out_len = 0x8000; /* 32 K */
out_buf = malloc(out_len);
} else {
- out_len = 0x7fffffff; /* no limit */
+ out_len = ((size_t)~0) - (size_t)out_buf; /* no limit */
}
if (!out_buf) {
error("Out of memory while allocating output buffer");
@@ -55,7 +59,7 @@ STATIC int INIT gunzip(unsigned char *buf, int len,
if (buf)
zbuf = buf;
else {
- zbuf = malloc(INBUF_LEN);
+ zbuf = malloc(GZIP_IOBUF_SIZE);
len = 0;
}
if (!zbuf) {
@@ -76,8 +80,11 @@ STATIC int INIT gunzip(unsigned char *buf, int len,
goto gunzip_nomem4;
}
+ if (!fill)
+ fill = nofill;
+
if (len == 0)
- len = fill(zbuf, INBUF_LEN);
+ len = fill(zbuf, GZIP_IOBUF_SIZE);
/* verify the gzip header */
if (len < 10 ||
@@ -92,13 +99,22 @@ STATIC int INIT gunzip(unsigned char *buf, int len,
* possible asciz filename)
*/
strm->next_in = zbuf + 10;
+ strm->avail_in = len - 10;
/* skip over asciz filename */
if (zbuf[3] & 0x8) {
- while (strm->next_in[0])
- strm->next_in++;
- strm->next_in++;
+ do {
+ /*
+ * If the filename doesn't fit into the buffer,
+ * the file is very probably corrupt. Don't try
+ * to read more data.
+ */
+ if (strm->avail_in == 0) {
+ error("header error");
+ goto gunzip_5;
+ }
+ --strm->avail_in;
+ } while (*strm->next_in++);
}
- strm->avail_in = len - (strm->next_in - zbuf);
strm->next_out = out_buf;
strm->avail_out = out_len;
@@ -113,7 +129,7 @@ STATIC int INIT gunzip(unsigned char *buf, int len,
while (rc == Z_OK) {
if (strm->avail_in == 0) {
/* TODO: handle case where both pos and fill are set */
- len = fill(zbuf, INBUF_LEN);
+ len = fill(zbuf, GZIP_IOBUF_SIZE);
if (len < 0) {
rc = -1;
error("read error");