Branch data Line data Source code
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 : : */ 9 : 0 : int zlib_inflate_blob(void *gunzip_buf, unsigned int sz, 10 : : const void *buf, unsigned int len) 11 : : { 12 : 0 : const u8 *zbuf = buf; 13 : 0 : struct z_stream_s *strm; 14 : 0 : int rc; 15 : : 16 : 0 : rc = -ENOMEM; 17 : 0 : strm = kmalloc(sizeof(*strm), GFP_KERNEL); 18 [ # # ]: 0 : if (strm == NULL) 19 : 0 : goto gunzip_nomem1; 20 [ # # ]: 0 : strm->workspace = kmalloc(zlib_inflate_workspacesize(), GFP_KERNEL); 21 [ # # ]: 0 : if (strm->workspace == NULL) 22 : 0 : 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 : 0 : strm->next_in = zbuf; 28 : 0 : strm->avail_in = len; 29 : 0 : strm->next_out = gunzip_buf; 30 : 0 : strm->avail_out = sz; 31 : : 32 : 0 : rc = zlib_inflateInit2(strm, -MAX_WBITS); 33 [ # # ]: 0 : if (rc == Z_OK) { 34 : 0 : rc = zlib_inflate(strm, Z_FINISH); 35 : : /* after Z_FINISH, only Z_STREAM_END is "we unpacked it all" */ 36 [ # # ]: 0 : if (rc == Z_STREAM_END) 37 : 0 : rc = sz - strm->avail_out; 38 : : else 39 : : rc = -EINVAL; 40 : 0 : zlib_inflateEnd(strm); 41 : : } else 42 : : rc = -EINVAL; 43 : : 44 : 0 : kfree(strm->workspace); 45 : 0 : gunzip_nomem2: 46 : 0 : kfree(strm); 47 : 0 : gunzip_nomem1: 48 : 0 : return rc; /* returns Z_OK (0) if successful */ 49 : : }