cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

zlib_wrapper.c (2612B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * Squashfs - a compressed read only filesystem for Linux
      4 *
      5 * Copyright (c) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
      6 * Phillip Lougher <phillip@squashfs.org.uk>
      7 *
      8 * zlib_wrapper.c
      9 */
     10
     11
     12#include <linux/mutex.h>
     13#include <linux/bio.h>
     14#include <linux/slab.h>
     15#include <linux/zlib.h>
     16#include <linux/vmalloc.h>
     17
     18#include "squashfs_fs.h"
     19#include "squashfs_fs_sb.h"
     20#include "squashfs.h"
     21#include "decompressor.h"
     22#include "page_actor.h"
     23
     24static void *zlib_init(struct squashfs_sb_info *dummy, void *buff)
     25{
     26	z_stream *stream = kmalloc(sizeof(z_stream), GFP_KERNEL);
     27	if (stream == NULL)
     28		goto failed;
     29	stream->workspace = vmalloc(zlib_inflate_workspacesize());
     30	if (stream->workspace == NULL)
     31		goto failed;
     32
     33	return stream;
     34
     35failed:
     36	ERROR("Failed to allocate zlib workspace\n");
     37	kfree(stream);
     38	return ERR_PTR(-ENOMEM);
     39}
     40
     41
     42static void zlib_free(void *strm)
     43{
     44	z_stream *stream = strm;
     45
     46	if (stream)
     47		vfree(stream->workspace);
     48	kfree(stream);
     49}
     50
     51
     52static int zlib_uncompress(struct squashfs_sb_info *msblk, void *strm,
     53	struct bio *bio, int offset, int length,
     54	struct squashfs_page_actor *output)
     55{
     56	struct bvec_iter_all iter_all = {};
     57	struct bio_vec *bvec = bvec_init_iter_all(&iter_all);
     58	int zlib_init = 0, error = 0;
     59	z_stream *stream = strm;
     60
     61	stream->avail_out = PAGE_SIZE;
     62	stream->next_out = squashfs_first_page(output);
     63	stream->avail_in = 0;
     64
     65	for (;;) {
     66		int zlib_err;
     67
     68		if (stream->avail_in == 0) {
     69			const void *data;
     70			int avail;
     71
     72			if (!bio_next_segment(bio, &iter_all)) {
     73				/* Z_STREAM_END must be reached. */
     74				error = -EIO;
     75				break;
     76			}
     77
     78			avail = min(length, ((int)bvec->bv_len) - offset);
     79			data = bvec_virt(bvec);
     80			length -= avail;
     81			stream->next_in = data + offset;
     82			stream->avail_in = avail;
     83			offset = 0;
     84		}
     85
     86		if (stream->avail_out == 0) {
     87			stream->next_out = squashfs_next_page(output);
     88			if (stream->next_out != NULL)
     89				stream->avail_out = PAGE_SIZE;
     90		}
     91
     92		if (!zlib_init) {
     93			zlib_err = zlib_inflateInit(stream);
     94			if (zlib_err != Z_OK) {
     95				error = -EIO;
     96				break;
     97			}
     98			zlib_init = 1;
     99		}
    100
    101		zlib_err = zlib_inflate(stream, Z_SYNC_FLUSH);
    102		if (zlib_err == Z_STREAM_END)
    103			break;
    104		if (zlib_err != Z_OK) {
    105			error = -EIO;
    106			break;
    107		}
    108	}
    109
    110	squashfs_finish_page(output);
    111
    112	if (!error)
    113		if (zlib_inflateEnd(stream) != Z_OK)
    114			error = -EIO;
    115
    116	return error ? error : stream->total_out;
    117}
    118
    119const struct squashfs_decompressor squashfs_zlib_comp_ops = {
    120	.init = zlib_init,
    121	.free = zlib_free,
    122	.decompress = zlib_uncompress,
    123	.id = ZLIB_COMPRESSION,
    124	.name = "zlib",
    125	.supported = 1
    126};
    127