isa-l/tests/fuzz/igzip_simple_round_trip_fuzz_test.c
Ilya Leoshkevich d3cfb2fb77 Fix s390 build
The goal of this patch is to make isa-l testsuite pass on s390 with
minimal changes to the library. The one and only reason isa-l does not
work on s390 at the moment is that s390 is big-endian, and isa-l
assumes little-endian at a lot of places.

There are two flavors of this: loading/storing integers from/to
memory, and overlapping structs. Loads/stores are already helpfully
wrapped by unaligned.h header, so replace the functions there with
endianness-aware variants. Solve struct member overlap by reversing
their order on big-endian.

Also, fix a couple of usages of uninitialized memory in the testsuite
(found with MemorySanitizer).

Fixes s390x part of #188.

Change-Id: Iaf14a113bd266900192cc8b44212f8a47a8c7753
Signed-off-by: Ilya Leoshkevich <iii@linux.ibm.com>
2022-01-04 11:06:17 -07:00

131 lines
3.4 KiB
C

#include <stdlib.h>
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include <assert.h>
#include <byteswap.h>
#include "igzip_lib.h"
#include "unaligned.h"
#define LEVEL_BITS 2
#define HEADER_BITS 3
#define LVL_BUF_BITS 3
#define LEVEL_BIT_MASK ((1<<LEVEL_BITS) - 1)
#define HEADER_BIT_MASK ((1<<HEADER_BITS) - 1)
#define TYPE0_HDR_SIZE 5
#define TYPE0_MAX_SIZE 65535
#define MIN(x,y) (((x) > (y)) ? y : x )
const int header_size[] = {
0, //IGZIP_DEFLATE
10, //IGZIP_GZIP
0, //IGZIP_GZIP_NO_HDR
2, //IGZIP_ZLIB
0, //IGZIP_ZLIB_NO_HDR
};
const int trailer_size[] = {
0, //IGZIP_DEFLATE
8, //IGZIP_GZIP
8, //IGZIP_GZIP_NO_HDR
4, //IGZIP_ZLIB
4, //IGZIP_ZLIB_NO_HDR
};
int LLVMFuzzerTestOneInput(const uint8_t * data, size_t size)
{
struct inflate_state istate;
struct isal_zstream cstate;
uint8_t *in_data = (uint8_t *) data;
int ret = 1;
// Parameter default
int level = 1;
int lev_buf_size = ISAL_DEF_LVL1_DEFAULT;
int wrapper_type = 0;
size_t cmp_buf_size = size + ISAL_DEF_MAX_HDR_SIZE;
// Parameters are set by one byte of data input
if (size > 1) {
uint8_t in_param = in_data[--size];
level = MIN(in_param & LEVEL_BIT_MASK, ISAL_DEF_MAX_LEVEL);
in_param >>= LEVEL_BITS;
wrapper_type = (in_param & HEADER_BIT_MASK) % (IGZIP_ZLIB_NO_HDR + 1);
in_param >>= HEADER_BITS;
switch (level) {
case 0:
lev_buf_size = ISAL_DEF_LVL0_MIN + (in_param) *
(ISAL_DEF_LVL0_EXTRA_LARGE / LEVEL_BIT_MASK);
break;
case 1:
lev_buf_size = ISAL_DEF_LVL1_MIN + (in_param) *
(ISAL_DEF_LVL1_EXTRA_LARGE / LEVEL_BIT_MASK);
break;
#ifdef ISAL_DEF_LVL2_MIN
case 2:
lev_buf_size = ISAL_DEF_LVL2_MIN + (in_param) *
(ISAL_DEF_LVL2_EXTRA_LARGE / LEVEL_BIT_MASK);
break;
#endif
#ifdef ISAL_DEF_LVL3_MIN
case 3:
lev_buf_size = ISAL_DEF_LVL3_MIN + (in_param) *
(ISAL_DEF_LVL3_EXTRA_LARGE / LEVEL_BIT_MASK);
break;
#endif
}
if (0 == level)
cmp_buf_size = 2 * size + ISAL_DEF_MAX_HDR_SIZE;
else
cmp_buf_size = size + 8 + (TYPE0_HDR_SIZE * (size / TYPE0_MAX_SIZE));
cmp_buf_size += header_size[wrapper_type] + trailer_size[wrapper_type];
}
uint8_t *isal_cmp_buf = (uint8_t *) malloc(cmp_buf_size);
uint8_t *isal_out_buf = (uint8_t *) malloc(size);
uint8_t *isal_lev_buf = (uint8_t *) malloc(lev_buf_size);
assert(NULL != isal_cmp_buf || NULL != isal_out_buf || NULL != isal_lev_buf);
isal_deflate_init(&cstate);
cstate.end_of_stream = 1;
cstate.flush = NO_FLUSH;
cstate.next_in = in_data;
cstate.avail_in = size;
cstate.next_out = isal_cmp_buf;
cstate.avail_out = cmp_buf_size;
cstate.level = level;
cstate.level_buf = isal_lev_buf;
cstate.level_buf_size = lev_buf_size;
cstate.gzip_flag = wrapper_type;
ret = isal_deflate_stateless(&cstate);
isal_inflate_init(&istate);
istate.next_in = isal_cmp_buf;
istate.avail_in = cstate.total_out;
istate.next_out = isal_out_buf;
istate.avail_out = size;
istate.crc_flag = wrapper_type;
ret |= isal_inflate_stateless(&istate);
ret |= memcmp(isal_out_buf, in_data, size);
// Check trailer
uint32_t crc = 0;
int trailer_idx = cstate.total_out - trailer_size[wrapper_type];
if (wrapper_type == IGZIP_GZIP || wrapper_type == IGZIP_GZIP_NO_HDR)
crc = load_le_u32(&isal_cmp_buf[trailer_idx]);
else if (wrapper_type == IGZIP_ZLIB || wrapper_type == IGZIP_ZLIB_NO_HDR)
crc = load_be_u32(&isal_cmp_buf[trailer_idx]);
assert(istate.crc == crc);
free(isal_cmp_buf);
free(isal_out_buf);
free(isal_lev_buf);
return ret;
}