aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/zlib_inflate/Makefile2
-rw-r--r--lib/zlib_inflate/inflate.c47
-rw-r--r--lib/zlib_inflate/infutil.c49
3 files changed, 50 insertions, 48 deletions
diff --git a/lib/zlib_inflate/Makefile b/lib/zlib_inflate/Makefile
index bf065482fa67..49f8ce5774d2 100644
--- a/lib/zlib_inflate/Makefile
+++ b/lib/zlib_inflate/Makefile
@@ -15,5 +15,5 @@
15 15
16obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate.o 16obj-$(CONFIG_ZLIB_INFLATE) += zlib_inflate.o
17 17
18zlib_inflate-objs := inffast.o inflate.o \ 18zlib_inflate-objs := inffast.o inflate.o infutil.o \
19 inftrees.o inflate_syms.o 19 inftrees.o inflate_syms.o
diff --git a/lib/zlib_inflate/inflate.c b/lib/zlib_inflate/inflate.c
index 0ad1ebf00947..f5ce87b0800e 100644
--- a/lib/zlib_inflate/inflate.c
+++ b/lib/zlib_inflate/inflate.c
@@ -916,50 +916,3 @@ int zlib_inflateIncomp(z_stream *z)
916 916
917 return Z_OK; 917 return Z_OK;
918} 918}
919
920#include <linux/errno.h>
921#include <linux/slab.h>
922#include <linux/vmalloc.h>
923
924/* Utility function: initialize zlib, unpack binary blob, clean up zlib,
925 * return len or negative error code. */
926int zlib_inflate_blob(void *gunzip_buf, unsigned sz, const void *buf, unsigned len)
927{
928 const u8 *zbuf = buf;
929 struct z_stream_s *strm;
930 int rc;
931
932 rc = -ENOMEM;
933 strm = kmalloc(sizeof(*strm), GFP_KERNEL);
934 if (strm == NULL)
935 goto gunzip_nomem1;
936 strm->workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL);
937 if (strm->workspace == NULL)
938 goto gunzip_nomem2;
939
940 /* gzip header (1f,8b,08... 10 bytes total + possible asciz filename)
941 * expected to be stripped from input */
942
943 strm->next_in = zbuf;
944 strm->avail_in = len;
945 strm->next_out = gunzip_buf;
946 strm->avail_out = sz;
947
948 rc = zlib_inflateInit2(strm, -MAX_WBITS);
949 if (rc == Z_OK) {
950 rc = zlib_inflate(strm, Z_FINISH);
951 /* after Z_FINISH, only Z_STREAM_END is "we unpacked it all" */
952 if (rc == Z_STREAM_END)
953 rc = sz - strm->avail_out;
954 else
955 rc = -EINVAL;
956 zlib_inflateEnd(strm);
957 } else
958 rc = -EINVAL;
959
960 kfree(strm->workspace);
961gunzip_nomem2:
962 kfree(strm);
963gunzip_nomem1:
964 return rc; /* returns Z_OK (0) if successful */
965}
diff --git a/lib/zlib_inflate/infutil.c b/lib/zlib_inflate/infutil.c
new file mode 100644
index 000000000000..4824c2cc7a09
--- /dev/null
+++ b/lib/zlib_inflate/infutil.c
@@ -0,0 +1,49 @@
1#include <linux/zutil.h>
2#include <linux/errno.h>
3#include <linux/slab.h>
4#include <linux/vmalloc.h>
5
6/* Utility function: initialize zlib, unpack binary blob, clean up zlib,
7 * return len or negative error code.
8 */
9int zlib_inflate_blob(void *gunzip_buf, unsigned int sz,
10 const void *buf, unsigned int len)
11{
12 const u8 *zbuf = buf;
13 struct z_stream_s *strm;
14 int rc;
15
16 rc = -ENOMEM;
17 strm = kmalloc(sizeof(*strm), GFP_KERNEL);
18 if (strm == NULL)
19 goto gunzip_nomem1;
20 strm->workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL);
21 if (strm->workspace == NULL)
22 goto gunzip_nomem2;
23
24 /* gzip header (1f,8b,08... 10 bytes total + possible asciz filename)
25 * expected to be stripped from input
26 */
27 strm->next_in = zbuf;
28 strm->avail_in = len;
29 strm->next_out = gunzip_buf;
30 strm->avail_out = sz;
31
32 rc = zlib_inflateInit2(strm, -MAX_WBITS);
33 if (rc == Z_OK) {
34 rc = zlib_inflate(strm, Z_FINISH);
35 /* after Z_FINISH, only Z_STREAM_END is "we unpacked it all" */
36 if (rc == Z_STREAM_END)
37 rc = sz - strm->avail_out;
38 else
39 rc = -EINVAL;
40 zlib_inflateEnd(strm);
41 } else
42 rc = -EINVAL;
43
44 kfree(strm->workspace);
45gunzip_nomem2:
46 kfree(strm);
47gunzip_nomem1:
48 return rc; /* returns Z_OK (0) if successful */
49}