Rizin
unix-like reverse engineering framework and cli tools
round_trip_stream_fuzzer.c File Reference
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "fuzz_helpers.h"
#include "lz4.h"
#include "lz4hc.h"

Go to the source code of this file.

Classes

struct  const_cursor_t
 
struct  cursor_t
 
struct  state_t
 

Macros

#define LZ4_STATIC_LINKING_ONLY
 
#define LZ4_HC_STATIC_LINKING_ONLY
 

Typedefs

typedef void(* round_trip_t) (state_t *state)
 

Functions

cursor_t cursor_create (size_t size)
 
void cursor_free (cursor_t cursor)
 
state_t state_create (char const *data, size_t size, uint32_t seed)
 
void state_free (state_t state)
 
static void state_reset (state_t *state, uint32_t seed)
 
static void state_decompress (state_t *state, char const *src, int srcSize)
 
static void state_checkRoundTrip (state_t const *state)
 
static size_t state_trimDict (state_t *state)
 
static void state_prefixRoundTrip (state_t *state)
 
static void state_extDictRoundTrip (state_t *state)
 
static void state_randomRoundTrip (state_t *state, round_trip_t rt0, round_trip_t rt1)
 
static void state_loadDictRoundTrip (state_t *state)
 
static void state_attachDictRoundTrip (state_t *state)
 
static void state_prefixHCRoundTrip (state_t *state)
 
static void state_extDictHCRoundTrip (state_t *state)
 
static void state_loadDictHCRoundTrip (state_t *state)
 
static void state_attachDictHCRoundTrip (state_t *state)
 
int LLVMFuzzerTestOneInput (const uint8_t *data, size_t size)
 

Variables

round_trip_t roundTrips []
 

Macro Definition Documentation

◆ LZ4_HC_STATIC_LINKING_ONLY

#define LZ4_HC_STATIC_LINKING_ONLY

Definition at line 15 of file round_trip_stream_fuzzer.c.

◆ LZ4_STATIC_LINKING_ONLY

#define LZ4_STATIC_LINKING_ONLY

This fuzz target performs a lz4 streaming round-trip test (compress & decompress), compares the result with the original, and calls abort() on corruption.

Definition at line 13 of file round_trip_stream_fuzzer.c.

Typedef Documentation

◆ round_trip_t

typedef void(* round_trip_t) (state_t *state)

Definition at line 51 of file round_trip_stream_fuzzer.c.

Function Documentation

◆ cursor_create()

cursor_t cursor_create ( size_t  size)

Definition at line 41 of file round_trip_stream_fuzzer.c.

42 {
43  cursor_t cursor;
44  cursor.buf = (char*)malloc(size);
45  cursor.size = size;
46  cursor.pos = 0;
47  FUZZ_ASSERT(cursor.buf);
48  return cursor;
49 }
#define FUZZ_ASSERT(cond)
Definition: fuzz_helpers.h:46
voidpf void uLong size
Definition: ioapi.h:138
void * malloc(size_t size)
Definition: malloc.c:123

References cursor_t::buf, FUZZ_ASSERT, malloc(), cursor_t::pos, and cursor_t::size.

Referenced by state_create(), state_extDictHCRoundTrip(), and state_extDictRoundTrip().

◆ cursor_free()

void cursor_free ( cursor_t  cursor)

Definition at line 53 of file round_trip_stream_fuzzer.c.

54 {
55  free(cursor.buf);
56 }
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130

References cursor_t::buf, and free().

Referenced by state_extDictHCRoundTrip(), state_extDictRoundTrip(), and state_free().

◆ LLVMFuzzerTestOneInput()

int LLVMFuzzerTestOneInput ( const uint8_t data,
size_t  size 
)

This fuzz target attempts to compress the fuzzed data with the simple compression function with an output buffer that may be too small to ensure that the compressor never crashes.

This fuzz target attempts to decompress the fuzzed data with the simple decompression function to ensure the decompressor never crashes.

This fuzz target performs a lz4 round-trip test (compress & decompress), compares the result with the original, and calls abort() on corruption.

Definition at line 285 of file round_trip_stream_fuzzer.c.

286 {
287  uint32_t seed = FUZZ_seed(&data, &size);
288  state_t state = state_create((char const*)data, size, seed);
289  const int n = sizeof(roundTrips) / sizeof(round_trip_t);
290  int i;
291 
292  for (i = 0; i < n; ++i) {
293  DEBUGLOG(2, "Round trip %d", i);
294  state_reset(&state, seed);
295  roundTrips[i](&state);
297  }
298 
299  state_free(state);
300 
301  return 0;
302 }
lzma_index ** i
Definition: index.h:629
FUZZ_STATIC uint32_t FUZZ_seed(uint8_t const **src, size_t *size)
Definition: fuzz_helpers.h:63
#define DEBUGLOG(l,...)
Definition: lz4.c:261
int n
Definition: mipsasm.c:19
state_t state_create(char const *data, size_t size, uint32_t seed)
static void state_reset(state_t *state, uint32_t seed)
void state_free(state_t state)
void(* round_trip_t)(state_t *state)
static void state_checkRoundTrip(state_t const *state)
round_trip_t roundTrips[]
unsigned int uint32_t
Definition: sftypes.h:29
Definition: dis.h:43

References arch, assert(), count, cs_close(), cs_disasm(), cs_disasm_iter(), cs_free(), cs_group_name(), cs_insn_name(), cs_malloc(), cs_open(), CS_OPT_DETAIL, CS_OPT_ON, cs_option(), cs_reg_name(), DEBUGLOG, test_evm::detail, err, FUZZ_seed(), handle, i, int, LLVMFuzzerInit(), LLVMFuzzerReturnOneInput(), n, NULL, outfile, platforms, printf(), PRIx64, roundTrips, snprintf, state_checkRoundTrip(), state_create(), state_free(), and state_reset().

Referenced by main().

◆ state_attachDictHCRoundTrip()

static void state_attachDictHCRoundTrip ( state_t state)
static

Definition at line 260 of file round_trip_stream_fuzzer.c.

261 {
262  char const* dict = state->data.buf;
263  size_t const dictSize = state_trimDict(state);
264  LZ4_streamHC_t* dictStream = LZ4_createStreamHC();
265  LZ4_setCompressionLevel(dictStream, state->level);
266  LZ4_loadDictHC(dictStream, dict, dictSize);
267  LZ4_attach_HC_dictionary(state->cstreamHC, dictStream);
268  LZ4_setStreamDecode(state->dstream, dict, dictSize);
271  LZ4_freeStreamHC(dictStream);
272 }
int LZ4_setStreamDecode(LZ4_streamDecode_t *LZ4_streamDecode, const char *dictionary, int dictSize)
Definition: lz4.c:2285
void LZ4_attach_HC_dictionary(LZ4_streamHC_t *working_stream, const LZ4_streamHC_t *dictionary_stream)
Definition: lz4hc.c:1077
int LZ4_freeStreamHC(LZ4_streamHC_t *LZ4_streamHCPtr)
Definition: lz4hc.c:994
LZ4_streamHC_t * LZ4_createStreamHC(void)
Definition: lz4hc.c:985
void LZ4_setCompressionLevel(LZ4_streamHC_t *LZ4_streamHCPtr, int compressionLevel)
Definition: lz4hc.c:1041
int LZ4_loadDictHC(LZ4_streamHC_t *LZ4_streamHCPtr, const char *dictionary, int dictSize)
Definition: lz4hc.c:1056
static size_t state_trimDict(state_t *state)
static void state_randomRoundTrip(state_t *state, round_trip_t rt0, round_trip_t rt1)
static void state_extDictHCRoundTrip(state_t *state)
static void state_prefixHCRoundTrip(state_t *state)

References LZ4_attach_HC_dictionary(), LZ4_createStreamHC(), LZ4_freeStreamHC(), LZ4_loadDictHC(), LZ4_setCompressionLevel(), LZ4_setStreamDecode(), state_extDictHCRoundTrip(), state_prefixHCRoundTrip(), state_randomRoundTrip(), and state_trimDict().

◆ state_attachDictRoundTrip()

static void state_attachDictRoundTrip ( state_t state)
static

Definition at line 197 of file round_trip_stream_fuzzer.c.

198 {
199  char const* dict = state->data.buf;
200  size_t const dictSize = state_trimDict(state);
201  LZ4_stream_t* dictStream = LZ4_createStream();
202  LZ4_loadDict(dictStream, dict, dictSize);
203  LZ4_attach_dictionary(state->cstream, dictStream);
204  LZ4_setStreamDecode(state->dstream, dict, dictSize);
206  LZ4_freeStream(dictStream);
207 }
int LZ4_loadDict(LZ4_stream_t *LZ4_dict, const char *dictionary, int dictSize)
Definition: lz4.c:1475
LZ4_stream_t * LZ4_createStream(void)
Definition: lz4.c:1423
int LZ4_freeStream(LZ4_stream_t *LZ4_stream)
Definition: lz4.c:1465
void LZ4_attach_dictionary(LZ4_stream_t *workingStream, const LZ4_stream_t *dictionaryStream)
Definition: lz4.c:1517
static void state_extDictRoundTrip(state_t *state)
static void state_prefixRoundTrip(state_t *state)

References LZ4_attach_dictionary(), LZ4_createStream(), LZ4_freeStream(), LZ4_loadDict(), LZ4_setStreamDecode(), state_extDictRoundTrip(), state_prefixRoundTrip(), state_randomRoundTrip(), and state_trimDict().

◆ state_checkRoundTrip()

static void state_checkRoundTrip ( state_t const state)
static

Definition at line 113 of file round_trip_stream_fuzzer.c.

114 {
115  char const* data = state->data.buf;
116  size_t const size = state->data.size;
117  FUZZ_ASSERT_MSG(size == state->roundTrip.pos, "Incorrect size!");
118  FUZZ_ASSERT_MSG(!memcmp(data, state->roundTrip.buf, size), "Corruption!");
119 }
#define FUZZ_ASSERT_MSG(cond, msg)
Definition: fuzz_helpers.h:41

References FUZZ_ASSERT_MSG.

Referenced by LLVMFuzzerTestOneInput().

◆ state_create()

state_t state_create ( char const data,
size_t  size,
uint32_t  seed 
)

Definition at line 58 of file round_trip_stream_fuzzer.c.

59 {
60  state_t state;
61 
62  state.seed = seed;
63 
64  state.data.buf = (char const*)data;
65  state.data.size = size;
66  state.data.pos = 0;
67 
68  /* Extra margin because we are streaming. */
69  state.compressed = cursor_create(1024 + 2 * LZ4_compressBound(size));
70  state.roundTrip = cursor_create(size);
71 
72  state.cstream = LZ4_createStream();
73  FUZZ_ASSERT(state.cstream);
74  state.cstreamHC = LZ4_createStreamHC();
75  FUZZ_ASSERT(state.cstream);
76  state.dstream = LZ4_createStreamDecode();
77  FUZZ_ASSERT(state.dstream);
78 
79  return state;
80 }
int LZ4_compressBound(int isize)
Definition: lz4.c:674
LZ4_streamDecode_t * LZ4_createStreamDecode(void)
Definition: lz4.c:2265
cursor_t cursor_create(size_t size)

References cursor_create(), FUZZ_ASSERT, LZ4_compressBound(), LZ4_createStream(), LZ4_createStreamDecode(), and LZ4_createStreamHC().

Referenced by LLVMFuzzerTestOneInput().

◆ state_decompress()

static void state_decompress ( state_t state,
char const src,
int  srcSize 
)
static

Definition at line 103 of file round_trip_stream_fuzzer.c.

104 {
105  char* dst = state->roundTrip.buf + state->roundTrip.pos;
106  int const dstCapacity = state->roundTrip.size - state->roundTrip.pos;
107  int const dSize = LZ4_decompress_safe_continue(state->dstream, src, dst,
108  srcSize, dstCapacity);
109  FUZZ_ASSERT(dSize >= 0);
110  state->roundTrip.pos += dSize;
111 }
lzma_index * src
Definition: index.h:567
LZ4_FORCE_O2 int LZ4_decompress_safe_continue(LZ4_streamDecode_t *LZ4_streamDecode, const char *source, char *dest, int compressedSize, int maxOutputSize)
Definition: lz4.c:2322
char int srcSize
Definition: lz4.h:697
char * dst
Definition: lz4.h:724

References dst, FUZZ_ASSERT, LZ4_decompress_safe_continue(), src, and srcSize.

Referenced by state_extDictHCRoundTrip(), state_extDictRoundTrip(), state_prefixHCRoundTrip(), and state_prefixRoundTrip().

◆ state_extDictHCRoundTrip()

static void state_extDictHCRoundTrip ( state_t state)
static

Definition at line 226 of file round_trip_stream_fuzzer.c.

227 {
228  int i = 0;
229  cursor_t data2 = cursor_create(state->data.size);
230  DEBUGLOG(2, "extDictHC");
231  memcpy(data2.buf, state->data.buf, state->data.size);
232  while (state->data.pos != state->data.size) {
233  char const* data = (i++ & 1) ? state->data.buf : data2.buf;
234  char const* src = data + state->data.pos;
235  char* dst = state->compressed.buf + state->compressed.pos;
236  int const srcRemaining = state->data.size - state->data.pos;
237  int const srcSize = FUZZ_rand32(&state->seed, 0, srcRemaining);
238  int const dstCapacity = state->compressed.size - state->compressed.pos;
239  int const cSize = LZ4_compress_HC_continue(state->cstreamHC, src, dst,
240  srcSize, dstCapacity);
241  FUZZ_ASSERT(cSize > 0);
242  DEBUGLOG(2, "srcSize = %d", srcSize);
243  state->data.pos += srcSize;
244  state->compressed.pos += cSize;
245  state_decompress(state, dst, cSize);
246  }
247  cursor_free(data2);
248 }
FUZZ_STATIC uint32_t FUZZ_rand32(uint32_t *state, uint32_t min, uint32_t max)
Definition: fuzz_helpers.h:85
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
int LZ4_compress_HC_continue(LZ4_streamHC_t *LZ4_streamHCPtr, const char *src, char *dst, int srcSize, int dstCapacity)
Definition: lz4hc.c:1138
static void state_decompress(state_t *state, char const *src, int srcSize)
void cursor_free(cursor_t cursor)

References cursor_t::buf, cursor_create(), cursor_free(), DEBUGLOG, dst, FUZZ_ASSERT, FUZZ_rand32(), i, LZ4_compress_HC_continue(), memcpy(), src, srcSize, and state_decompress().

Referenced by state_attachDictHCRoundTrip(), and state_loadDictHCRoundTrip().

◆ state_extDictRoundTrip()

static void state_extDictRoundTrip ( state_t state)
static

Definition at line 156 of file round_trip_stream_fuzzer.c.

157 {
158  int i = 0;
159  cursor_t data2 = cursor_create(state->data.size);
160  memcpy(data2.buf, state->data.buf, state->data.size);
161  while (state->data.pos != state->data.size) {
162  char const* data = (i++ & 1) ? state->data.buf : data2.buf;
163  char const* src = data + state->data.pos;
164  char* dst = state->compressed.buf + state->compressed.pos;
165  int const srcRemaining = state->data.size - state->data.pos;
166  int const srcSize = FUZZ_rand32(&state->seed, 0, srcRemaining);
167  int const dstCapacity = state->compressed.size - state->compressed.pos;
168  int const cSize = LZ4_compress_fast_continue(state->cstream, src, dst,
169  srcSize, dstCapacity, 0);
170  FUZZ_ASSERT(cSize > 0);
171  state->data.pos += srcSize;
172  state->compressed.pos += cSize;
173  state_decompress(state, dst, cSize);
174  }
175  cursor_free(data2);
176 }
int LZ4_compress_fast_continue(LZ4_stream_t *LZ4_stream, const char *source, char *dest, int inputSize, int maxOutputSize, int acceleration)
Definition: lz4.c:1565

References cursor_t::buf, cursor_create(), cursor_free(), dst, FUZZ_ASSERT, FUZZ_rand32(), i, LZ4_compress_fast_continue(), memcpy(), src, srcSize, and state_decompress().

Referenced by state_attachDictRoundTrip(), and state_loadDictRoundTrip().

◆ state_free()

void state_free ( state_t  state)

Definition at line 82 of file round_trip_stream_fuzzer.c.

83 {
84  cursor_free(state.compressed);
85  cursor_free(state.roundTrip);
86  LZ4_freeStream(state.cstream);
87  LZ4_freeStreamHC(state.cstreamHC);
88  LZ4_freeStreamDecode(state.dstream);
89 }
int LZ4_freeStreamDecode(LZ4_streamDecode_t *LZ4_stream)
Definition: lz4.c:2272

References cursor_free(), LZ4_freeStream(), LZ4_freeStreamDecode(), and LZ4_freeStreamHC().

Referenced by LLVMFuzzerTestOneInput().

◆ state_loadDictHCRoundTrip()

static void state_loadDictHCRoundTrip ( state_t state)
static

Definition at line 250 of file round_trip_stream_fuzzer.c.

251 {
252  char const* dict = state->data.buf;
253  size_t const dictSize = state_trimDict(state);
254  LZ4_loadDictHC(state->cstreamHC, dict, dictSize);
255  LZ4_setStreamDecode(state->dstream, dict, dictSize);
258 }

References LZ4_loadDictHC(), LZ4_setStreamDecode(), state_extDictHCRoundTrip(), state_prefixHCRoundTrip(), state_randomRoundTrip(), and state_trimDict().

◆ state_loadDictRoundTrip()

static void state_loadDictRoundTrip ( state_t state)
static

Definition at line 188 of file round_trip_stream_fuzzer.c.

189 {
190  char const* dict = state->data.buf;
191  size_t const dictSize = state_trimDict(state);
192  LZ4_loadDict(state->cstream, dict, dictSize);
193  LZ4_setStreamDecode(state->dstream, dict, dictSize);
195 }

References LZ4_loadDict(), LZ4_setStreamDecode(), state_extDictRoundTrip(), state_prefixRoundTrip(), state_randomRoundTrip(), and state_trimDict().

◆ state_prefixHCRoundTrip()

static void state_prefixHCRoundTrip ( state_t state)
static

Definition at line 209 of file round_trip_stream_fuzzer.c.

210 {
211  while (state->data.pos != state->data.size) {
212  char const* src = state->data.buf + state->data.pos;
213  char* dst = state->compressed.buf + state->compressed.pos;
214  int const srcRemaining = state->data.size - state->data.pos;
215  int const srcSize = FUZZ_rand32(&state->seed, 0, srcRemaining);
216  int const dstCapacity = state->compressed.size - state->compressed.pos;
217  int const cSize = LZ4_compress_HC_continue(state->cstreamHC, src, dst,
218  srcSize, dstCapacity);
219  FUZZ_ASSERT(cSize > 0);
220  state->data.pos += srcSize;
221  state->compressed.pos += cSize;
222  state_decompress(state, dst, cSize);
223  }
224 }

References dst, FUZZ_ASSERT, FUZZ_rand32(), LZ4_compress_HC_continue(), src, srcSize, and state_decompress().

Referenced by state_attachDictHCRoundTrip(), and state_loadDictHCRoundTrip().

◆ state_prefixRoundTrip()

static void state_prefixRoundTrip ( state_t state)
static

Definition at line 139 of file round_trip_stream_fuzzer.c.

140 {
141  while (state->data.pos != state->data.size) {
142  char const* src = state->data.buf + state->data.pos;
143  char* dst = state->compressed.buf + state->compressed.pos;
144  int const srcRemaining = state->data.size - state->data.pos;
145  int const srcSize = FUZZ_rand32(&state->seed, 0, srcRemaining);
146  int const dstCapacity = state->compressed.size - state->compressed.pos;
147  int const cSize = LZ4_compress_fast_continue(state->cstream, src, dst,
148  srcSize, dstCapacity, 0);
149  FUZZ_ASSERT(cSize > 0);
150  state->data.pos += srcSize;
151  state->compressed.pos += cSize;
152  state_decompress(state, dst, cSize);
153  }
154 }

References dst, FUZZ_ASSERT, FUZZ_rand32(), LZ4_compress_fast_continue(), src, srcSize, and state_decompress().

Referenced by state_attachDictRoundTrip(), and state_loadDictRoundTrip().

◆ state_randomRoundTrip()

static void state_randomRoundTrip ( state_t state,
round_trip_t  rt0,
round_trip_t  rt1 
)
static

Definition at line 178 of file round_trip_stream_fuzzer.c.

180 {
181  if (FUZZ_rand32(&state->seed, 0, 1)) {
182  rt0(state);
183  } else {
184  rt1(state);
185  }
186 }

References FUZZ_rand32().

Referenced by state_attachDictHCRoundTrip(), state_attachDictRoundTrip(), state_loadDictHCRoundTrip(), and state_loadDictRoundTrip().

◆ state_reset()

static void state_reset ( state_t state,
uint32_t  seed 
)
static

Definition at line 91 of file round_trip_stream_fuzzer.c.

92 {
94  LZ4_resetStream_fast(state->cstream);
95  LZ4_resetStreamHC_fast(state->cstreamHC, state->level);
96  LZ4_setStreamDecode(state->dstream, NULL, 0);
97  state->data.pos = 0;
98  state->compressed.pos = 0;
99  state->roundTrip.pos = 0;
100  state->seed = seed;
101 }
#define NULL
Definition: cris-opc.c:27
void LZ4_resetStream_fast(LZ4_stream_t *ctx)
Definition: lz4.c:1461
void LZ4_resetStreamHC_fast(LZ4_streamHC_t *LZ4_streamHCPtr, int compressionLevel)
Definition: lz4hc.c:1027
#define LZ4HC_CLEVEL_MAX
Definition: lz4hc.h:50
#define LZ4HC_CLEVEL_MIN
Definition: lz4hc.h:47

References FUZZ_rand32(), LZ4_resetStream_fast(), LZ4_resetStreamHC_fast(), LZ4_setStreamDecode(), LZ4HC_CLEVEL_MAX, LZ4HC_CLEVEL_MIN, and NULL.

Referenced by LLVMFuzzerTestOneInput().

◆ state_trimDict()

static size_t state_trimDict ( state_t state)
static

Picks a dictionary size and trims the dictionary off of the data. We copy the dictionary to the roundTrip so our validation passes.

Definition at line 125 of file round_trip_stream_fuzzer.c.

126 {
127  /* 64 KB is the max dict size, allow slightly beyond that to test trim. */
128  uint32_t maxDictSize = MIN(70 * 1024, state->data.size);
129  size_t const dictSize = FUZZ_rand32(&state->seed, 0, maxDictSize);
130  DEBUGLOG(2, "dictSize = %zu", dictSize);
131  FUZZ_ASSERT(state->data.pos == 0);
132  FUZZ_ASSERT(state->roundTrip.pos == 0);
133  memcpy(state->roundTrip.buf, state->data.buf, dictSize);
134  state->data.pos += dictSize;
135  state->roundTrip.pos += dictSize;
136  return dictSize;
137 }
#define MIN(x, y)
Definition: utils.h:59

References DEBUGLOG, FUZZ_ASSERT, FUZZ_rand32(), memcpy(), and MIN.

Referenced by state_attachDictHCRoundTrip(), state_attachDictRoundTrip(), state_loadDictHCRoundTrip(), and state_loadDictRoundTrip().

Variable Documentation

◆ roundTrips

round_trip_t roundTrips[]
Initial value:
= {
}
static void state_attachDictRoundTrip(state_t *state)
static void state_loadDictRoundTrip(state_t *state)
static void state_loadDictHCRoundTrip(state_t *state)
static void state_attachDictHCRoundTrip(state_t *state)

Definition at line 274 of file round_trip_stream_fuzzer.c.

Referenced by LLVMFuzzerTestOneInput().