]> git.proxmox.com Git - ceph.git/blob - ceph/src/isa-l/tests/fuzz/igzip_simple_round_trip_fuzz_test.c
Import ceph 15.2.8
[ceph.git] / ceph / src / isa-l / tests / fuzz / igzip_simple_round_trip_fuzz_test.c
1 #include <stdlib.h>
2 #include <stdint.h>
3 #include <stddef.h>
4 #include <string.h>
5 #include <assert.h>
6 #include <byteswap.h>
7 #include "igzip_lib.h"
8 #include "unaligned.h"
9
10 #define LEVEL_BITS 2
11 #define HEADER_BITS 3
12 #define LVL_BUF_BITS 3
13
14 #define LEVEL_BIT_MASK ((1<<LEVEL_BITS) - 1)
15 #define HEADER_BIT_MASK ((1<<HEADER_BITS) - 1)
16 #define TYPE0_HDR_SIZE 5
17 #define TYPE0_MAX_SIZE 65535
18
19 #define MIN(x,y) (((x) > (y)) ? y : x )
20
21 const int header_size[] = {
22 0, //IGZIP_DEFLATE
23 10, //IGZIP_GZIP
24 0, //IGZIP_GZIP_NO_HDR
25 2, //IGZIP_ZLIB
26 0, //IGZIP_ZLIB_NO_HDR
27 };
28
29 const int trailer_size[] = {
30 0, //IGZIP_DEFLATE
31 8, //IGZIP_GZIP
32 8, //IGZIP_GZIP_NO_HDR
33 4, //IGZIP_ZLIB
34 4, //IGZIP_ZLIB_NO_HDR
35 };
36
37 int LLVMFuzzerTestOneInput(const uint8_t * data, size_t size)
38 {
39 struct inflate_state istate;
40 struct isal_zstream cstate;
41 uint8_t *in_data = (uint8_t *) data;
42 int ret = 1;
43
44 // Parameter default
45 int level = 1;
46 int lev_buf_size = ISAL_DEF_LVL1_DEFAULT;
47 int wrapper_type = 0;
48 size_t cmp_buf_size = size + ISAL_DEF_MAX_HDR_SIZE;
49
50 // Parameters are set by one byte of data input
51 if (size > 1) {
52 uint8_t in_param = in_data[--size];
53 level = MIN(in_param & LEVEL_BIT_MASK, ISAL_DEF_MAX_LEVEL);
54 in_param >>= LEVEL_BITS;
55
56 wrapper_type = (in_param & HEADER_BIT_MASK) % (IGZIP_ZLIB_NO_HDR + 1);
57 in_param >>= HEADER_BITS;
58
59 switch (level) {
60 case 0:
61 lev_buf_size = ISAL_DEF_LVL0_MIN + (in_param) *
62 (ISAL_DEF_LVL0_EXTRA_LARGE / LEVEL_BIT_MASK);
63 break;
64 case 1:
65 lev_buf_size = ISAL_DEF_LVL1_MIN + (in_param) *
66 (ISAL_DEF_LVL1_EXTRA_LARGE / LEVEL_BIT_MASK);
67 break;
68 #ifdef ISAL_DEF_LVL2_MIN
69 case 2:
70 lev_buf_size = ISAL_DEF_LVL2_MIN + (in_param) *
71 (ISAL_DEF_LVL2_EXTRA_LARGE / LEVEL_BIT_MASK);
72 break;
73 #endif
74 #ifdef ISAL_DEF_LVL3_MIN
75 case 3:
76 lev_buf_size = ISAL_DEF_LVL3_MIN + (in_param) *
77 (ISAL_DEF_LVL3_EXTRA_LARGE / LEVEL_BIT_MASK);
78 break;
79 #endif
80 }
81 if (0 == level)
82 cmp_buf_size = 2 * size + ISAL_DEF_MAX_HDR_SIZE;
83 else
84 cmp_buf_size = size + 8 + (TYPE0_HDR_SIZE * (size / TYPE0_MAX_SIZE));
85
86 cmp_buf_size += header_size[wrapper_type] + trailer_size[wrapper_type];
87 }
88
89 uint8_t *isal_cmp_buf = (uint8_t *) malloc(cmp_buf_size);
90 uint8_t *isal_out_buf = (uint8_t *) malloc(size);
91 uint8_t *isal_lev_buf = (uint8_t *) malloc(lev_buf_size);
92 assert(NULL != isal_cmp_buf || NULL != isal_out_buf || NULL != isal_lev_buf);
93
94 isal_deflate_init(&cstate);
95 cstate.end_of_stream = 1;
96 cstate.flush = NO_FLUSH;
97 cstate.next_in = in_data;
98 cstate.avail_in = size;
99 cstate.next_out = isal_cmp_buf;
100 cstate.avail_out = cmp_buf_size;
101 cstate.level = level;
102 cstate.level_buf = isal_lev_buf;
103 cstate.level_buf_size = lev_buf_size;
104 cstate.gzip_flag = wrapper_type;
105 ret = isal_deflate_stateless(&cstate);
106
107 isal_inflate_init(&istate);
108 istate.next_in = isal_cmp_buf;
109 istate.avail_in = cstate.total_out;
110 istate.next_out = isal_out_buf;
111 istate.avail_out = size;
112 istate.crc_flag = wrapper_type;
113 ret |= isal_inflate_stateless(&istate);
114 ret |= memcmp(isal_out_buf, in_data, size);
115
116 // Check trailer
117 uint32_t crc = 0;
118 int trailer_idx = cstate.total_out - trailer_size[wrapper_type];
119
120 if (wrapper_type == IGZIP_GZIP || wrapper_type == IGZIP_GZIP_NO_HDR)
121 crc = load_u32(&isal_cmp_buf[trailer_idx]);
122 else if (wrapper_type == IGZIP_ZLIB || wrapper_type == IGZIP_ZLIB_NO_HDR)
123 crc = bswap_32(load_u32(&isal_cmp_buf[trailer_idx]));
124
125 assert(istate.crc == crc);
126 free(isal_cmp_buf);
127 free(isal_out_buf);
128 free(isal_lev_buf);
129 return ret;
130 }