Embedded SDK
Embedded SDK
Loading...
Searching...
No Matches
fuzz_mutator.h
Go to the documentation of this file.
1#pragma once
20#include <stddef.h>
21#include <stdint.h>
22#include <string.h>
23
24#ifndef FUZZ_APP_DATA_OFF
25#define FUZZ_APP_DATA_OFF 0
26#endif
27#ifndef FUZZ_APP_DATA_LEN
28#define FUZZ_APP_DATA_LEN 0
29#endif
30
31extern size_t LLVMFuzzerMutate(uint8_t *data, size_t size, size_t max_size);
32extern const size_t absolution_globals_size __attribute__((weak));
33
34enum {
41};
42
43#if FUZZ_APP_DATA_LEN > 0
44enum {
45 FUZZ_MUT_STRUCTURED_APP_DATA_CUTOFF = 40,
47};
48#else
49enum {
51};
52#endif
53
54static size_t fuzz_prefix_size(void)
55{
56 size_t prefix_size = FUZZ_PREFIX_SIZE_FALLBACK;
57
58 if (&absolution_globals_size != NULL && absolution_globals_size != 0) {
59 prefix_size = absolution_globals_size;
60 }
61 return prefix_size;
62}
63
64static int fuzz_split_is_valid(size_t prefix_size, size_t max_size)
65{
66 if (prefix_size == 0 || prefix_size >= max_size) {
67 return 0;
68 }
69
70 if (FUZZ_CTRL_OFF + FUZZ_CTRL_LEN > prefix_size) {
71 return 0;
72 }
73
74#if FUZZ_APP_DATA_LEN > 0
75 if (FUZZ_APP_DATA_OFF + FUZZ_APP_DATA_LEN > prefix_size) {
76 return 0;
77 }
78#endif
79 return 1;
80}
81
82static size_t fuzz_bootstrap_input(uint8_t *data, size_t size, size_t prefix_size, size_t max_size)
83{
84 if (size == 0) {
85 if (prefix_size + FUZZ_MUT_INITIAL_POST_PREFIX_SIZE <= max_size) {
86 size = prefix_size + FUZZ_MUT_INITIAL_POST_PREFIX_SIZE;
87 }
88 else {
89 size = max_size;
90 }
91 memset(data, 0, size);
92 }
93 return size;
94}
95
96static void fuzz_mutate_window(uint8_t *data, size_t data_len, size_t max_span, unsigned int pick)
97{
98 if (data_len == 0) {
99 return;
100 }
101
102 size_t start = pick % data_len;
103 size_t span = data_len - start;
104 if (span > max_span) {
105 span = max_span;
106 }
107
108 (void) LLVMFuzzerMutate(data + start, span, span);
109}
110
111static void fuzz_mutate_prefix_window(uint8_t *data, size_t prefix_size, unsigned int pick)
112{
113 fuzz_mutate_window(data, prefix_size, FUZZ_MUT_PREFIX_WINDOW_MAX, pick);
114}
115
116static void fuzz_mutate_ctrl(uint8_t *data)
117{
118 (void) LLVMFuzzerMutate(data + FUZZ_CTRL_OFF, FUZZ_CTRL_LEN, FUZZ_CTRL_LEN);
119}
120
121static size_t fuzz_mutate_post_prefix(uint8_t *data, size_t size, size_t max_size)
122{
123 return LLVMFuzzerMutate(data, size, max_size);
124}
125
126static int fuzz_should_inject_token(unsigned int seed)
127{
128 return ((seed >> 4) & FUZZ_MUT_TOKEN_INJECT_MASK) == 0;
129}
130
131#if FUZZ_APP_DATA_LEN > 0
132static void fuzz_mutate_app_data(uint8_t *data, unsigned int seed)
133{
136}
137
138#ifdef FUZZ_INJECT_TOKEN
139static void fuzz_maybe_inject_structured_token(uint8_t *data, unsigned int seed)
140{
141 if (fuzz_should_inject_token(seed)) {
142 FUZZ_INJECT_TOKEN(data + FUZZ_APP_DATA_OFF, FUZZ_APP_DATA_LEN, seed >> 16);
143 }
144}
145#endif
146#endif
147
148#ifdef FUZZ_INJECT_TOKEN
149static void fuzz_maybe_inject_raw_token(uint8_t *data, size_t post_prefix_size, unsigned int seed)
150{
151 if (post_prefix_size > 0 && fuzz_should_inject_token(seed)) {
152 FUZZ_INJECT_TOKEN(data, post_prefix_size, seed >> 16);
153 }
154}
155#endif
156
157static size_t fuzz_mutate_structured(uint8_t *data,
158 size_t prefix_size,
159 size_t post_prefix_size,
160 size_t max_size,
161 unsigned int seed)
162{
163 unsigned int dice = seed % 100;
164
165#if FUZZ_APP_DATA_LEN > 0
166 if (dice < FUZZ_MUT_STRUCTURED_APP_DATA_CUTOFF) {
167 fuzz_mutate_app_data(data, seed);
168 }
170#else
172#endif
173 post_prefix_size
174 = fuzz_mutate_post_prefix(data + prefix_size, post_prefix_size, max_size - prefix_size);
175 }
176 else if (dice < FUZZ_MUT_STRUCTURED_CTRL_CUTOFF) {
177 fuzz_mutate_ctrl(data);
178 }
179 else {
180 fuzz_mutate_prefix_window(data, prefix_size, seed >> 8);
181 }
182
183#if FUZZ_APP_DATA_LEN > 0
184#ifdef FUZZ_INJECT_TOKEN
185 fuzz_maybe_inject_structured_token(data, seed);
186#endif
187#endif
188
189 return post_prefix_size;
190}
191
192static size_t fuzz_mutate_raw(uint8_t *data,
193 size_t prefix_size,
194 size_t post_prefix_size,
195 size_t max_size,
196 unsigned int seed)
197{
198 if ((seed & FUZZ_MUT_RAW_PREFIX_MASK) == 0) {
199 fuzz_mutate_prefix_window(data, prefix_size, seed >> 2);
200 }
201
202 post_prefix_size
203 = fuzz_mutate_post_prefix(data + prefix_size, post_prefix_size, max_size - prefix_size);
204
205#ifdef FUZZ_INJECT_TOKEN
206 fuzz_maybe_inject_raw_token(data + prefix_size, post_prefix_size, seed);
207#endif
208
209 return post_prefix_size;
210}
211
212static size_t fuzz_mutate_with_split(uint8_t *data, size_t size, size_t max_size, unsigned int seed)
213{
214 size_t prefix_size = fuzz_prefix_size();
215 size_t post_prefix_size;
216
217 if (!fuzz_split_is_valid(prefix_size, max_size)) {
218 return LLVMFuzzerMutate(data, size, max_size);
219 }
220
221 size = fuzz_bootstrap_input(data, size, prefix_size, max_size);
222
223 if (size <= prefix_size) {
224 return LLVMFuzzerMutate(data, size, max_size);
225 }
226
227 post_prefix_size = size - prefix_size;
228
229 if (fuzz_lane_is_structured(data, prefix_size)) {
230 post_prefix_size
231 = fuzz_mutate_structured(data, prefix_size, post_prefix_size, max_size, seed);
232 }
233 else {
234 post_prefix_size = fuzz_mutate_raw(data, prefix_size, post_prefix_size, max_size, seed);
235 }
236
237 return prefix_size + post_prefix_size;
238}
239
240static size_t fuzz_custom_mutator(uint8_t *data, size_t size, size_t max_size, unsigned int seed)
241{
242 return fuzz_mutate_with_split(data, size, max_size, seed);
243}
static size_t fuzz_prefix_size(void)
@ FUZZ_MUT_RAW_PREFIX_MASK
@ FUZZ_MUT_STRUCTURED_CTRL_CUTOFF
@ FUZZ_MUT_TOKEN_INJECT_MASK
@ FUZZ_MUT_APP_DATA_WINDOW_MAX
@ FUZZ_MUT_PREFIX_WINDOW_MAX
@ FUZZ_MUT_INITIAL_POST_PREFIX_SIZE
static size_t fuzz_mutate_raw(uint8_t *data, size_t prefix_size, size_t post_prefix_size, size_t max_size, unsigned int seed)
static void fuzz_mutate_prefix_window(uint8_t *data, size_t prefix_size, unsigned int pick)
#define FUZZ_APP_DATA_OFF
static size_t fuzz_mutate_with_split(uint8_t *data, size_t size, size_t max_size, unsigned int seed)
static void fuzz_mutate_ctrl(uint8_t *data)
static size_t fuzz_mutate_post_prefix(uint8_t *data, size_t size, size_t max_size)
static size_t fuzz_mutate_structured(uint8_t *data, size_t prefix_size, size_t post_prefix_size, size_t max_size, unsigned int seed)
static int fuzz_split_is_valid(size_t prefix_size, size_t max_size)
#define FUZZ_APP_DATA_LEN
const size_t absolution_globals_size __attribute__((weak))
static size_t fuzz_bootstrap_input(uint8_t *data, size_t size, size_t prefix_size, size_t max_size)
size_t LLVMFuzzerMutate(uint8_t *data, size_t size, size_t max_size)
@ FUZZ_MUT_STRUCTURED_POST_PREFIX_CUTOFF
static int fuzz_should_inject_token(unsigned int seed)
static size_t fuzz_custom_mutator(uint8_t *data, size_t size, size_t max_size, unsigned int seed)
static void fuzz_mutate_window(uint8_t *data, size_t data_len, size_t max_span, unsigned int pick)