linux/lib/zlib_inflate/infutil.c
<<
>>
Prefs
   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}
  50