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.c (1793B)


      1// SPDX-License-Identifier: GPL-2.0
      2#include <fcntl.h>
      3#include <stdio.h>
      4#include <string.h>
      5#include <unistd.h>
      6#include <sys/stat.h>
      7#include <sys/mman.h>
      8#include <zlib.h>
      9#include <linux/compiler.h>
     10#include <internal/lib.h>
     11
     12#include "util/compress.h"
     13
     14#define CHUNK_SIZE  16384
     15
     16int gzip_decompress_to_file(const char *input, int output_fd)
     17{
     18	int ret = Z_STREAM_ERROR;
     19	int input_fd;
     20	void *ptr;
     21	int len;
     22	struct stat stbuf;
     23	unsigned char buf[CHUNK_SIZE];
     24	z_stream zs = {
     25		.zalloc		= Z_NULL,
     26		.zfree		= Z_NULL,
     27		.opaque		= Z_NULL,
     28		.avail_in	= 0,
     29		.next_in	= Z_NULL,
     30	};
     31
     32	input_fd = open(input, O_RDONLY);
     33	if (input_fd < 0)
     34		return -1;
     35
     36	if (fstat(input_fd, &stbuf) < 0)
     37		goto out_close;
     38
     39	ptr = mmap(NULL, stbuf.st_size, PROT_READ, MAP_PRIVATE, input_fd, 0);
     40	if (ptr == MAP_FAILED)
     41		goto out_close;
     42
     43	if (inflateInit2(&zs, 16 + MAX_WBITS) != Z_OK)
     44		goto out_unmap;
     45
     46	zs.next_in = ptr;
     47	zs.avail_in = stbuf.st_size;
     48
     49	do {
     50		zs.next_out = buf;
     51		zs.avail_out = CHUNK_SIZE;
     52
     53		ret = inflate(&zs, Z_NO_FLUSH);
     54		switch (ret) {
     55		case Z_NEED_DICT:
     56			ret = Z_DATA_ERROR;
     57			/* fall through */
     58		case Z_DATA_ERROR:
     59		case Z_MEM_ERROR:
     60			goto out;
     61		default:
     62			break;
     63		}
     64
     65		len = CHUNK_SIZE - zs.avail_out;
     66		if (writen(output_fd, buf, len) != len) {
     67			ret = Z_DATA_ERROR;
     68			goto out;
     69		}
     70
     71	} while (ret != Z_STREAM_END);
     72
     73out:
     74	inflateEnd(&zs);
     75out_unmap:
     76	munmap(ptr, stbuf.st_size);
     77out_close:
     78	close(input_fd);
     79
     80	return ret == Z_STREAM_END ? 0 : -1;
     81}
     82
     83bool gzip_is_compressed(const char *input)
     84{
     85	int fd = open(input, O_RDONLY);
     86	const uint8_t magic[2] = { 0x1f, 0x8b };
     87	char buf[2] = { 0 };
     88	ssize_t rc;
     89
     90	if (fd < 0)
     91		return -1;
     92
     93	rc = read(fd, buf, sizeof(buf));
     94	close(fd);
     95	return rc == sizeof(buf) ?
     96	       memcmp(buf, magic, sizeof(buf)) == 0 : false;
     97}