0001 #include <linux/zutil.h>
0002 #include <linux/errno.h>
0003 #include <linux/slab.h>
0004 #include <linux/vmalloc.h>
0005
0006
0007
0008
0009 int zlib_inflate_blob(void *gunzip_buf, unsigned int sz,
0010 const void *buf, unsigned int len)
0011 {
0012 const u8 *zbuf = buf;
0013 struct z_stream_s *strm;
0014 int rc;
0015
0016 rc = -ENOMEM;
0017 strm = kmalloc(sizeof(*strm), GFP_KERNEL);
0018 if (strm == NULL)
0019 goto gunzip_nomem1;
0020 strm->workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL);
0021 if (strm->workspace == NULL)
0022 goto gunzip_nomem2;
0023
0024
0025
0026
0027 strm->next_in = zbuf;
0028 strm->avail_in = len;
0029 strm->next_out = gunzip_buf;
0030 strm->avail_out = sz;
0031
0032 rc = zlib_inflateInit2(strm, -MAX_WBITS);
0033 if (rc == Z_OK) {
0034 rc = zlib_inflate(strm, Z_FINISH);
0035
0036 if (rc == Z_STREAM_END)
0037 rc = sz - strm->avail_out;
0038 else
0039 rc = -EINVAL;
0040 zlib_inflateEnd(strm);
0041 } else
0042 rc = -EINVAL;
0043
0044 kfree(strm->workspace);
0045 gunzip_nomem2:
0046 kfree(strm);
0047 gunzip_nomem1:
0048 return rc;
0049 }