1 /*
2 *
3 * honggfuzz - run->dynamicFilefer mangling routines
4 * -----------------------------------------
5 *
6 * Author:
7 * Robert Swiecki <swiecki@google.com>
8 *
9 * Copyright 2010-2015 by Google Inc. All Rights Reserved.
10 *
11 * Licensed under the Apache License, Version 2.0 (the "License"); you may
12 * not use this file except in compliance with the License. You may obtain
13 * a copy of the License at
14 *
15 * http://www.apache.org/licenses/LICENSE-2.0
16 *
17 * Unless required by applicable law or agreed to in writing, software
18 * distributed under the License is distributed on an "AS IS" BASIS,
19 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
20 * implied. See the License for the specific language governing
21 * permissions and limitations under the License.
22 *
23 */
24
25 #include "mangle.h"
26
27 #include <inttypes.h>
28 #include <math.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <sys/mman.h>
33 #include <unistd.h>
34
35 #include "libcommon/common.h"
36 #include "libcommon/log.h"
37 #include "libcommon/util.h"
38
mangle_Overwrite(run_t * run,const uint8_t * src,size_t off,size_t sz)39 static inline void mangle_Overwrite(run_t* run, const uint8_t* src, size_t off, size_t sz) {
40 size_t maxToCopy = run->dynamicFileSz - off;
41 if (sz > maxToCopy) {
42 sz = maxToCopy;
43 }
44
45 memmove(&run->dynamicFile[off], src, sz);
46 }
47
mangle_Move(run_t * run,size_t off_from,size_t off_to,size_t len)48 static inline void mangle_Move(run_t* run, size_t off_from, size_t off_to, size_t len) {
49 if (off_from >= run->dynamicFileSz) {
50 return;
51 }
52 if (off_to >= run->dynamicFileSz) {
53 return;
54 }
55
56 ssize_t len_from = (ssize_t)run->dynamicFileSz - off_from - 1;
57 ssize_t len_to = (ssize_t)run->dynamicFileSz - off_to - 1;
58
59 if ((ssize_t)len > len_from) {
60 len = len_from;
61 }
62 if ((ssize_t)len > len_to) {
63 len = len_to;
64 }
65
66 memmove(&run->dynamicFile[off_to], &run->dynamicFile[off_from], len);
67 }
68
mangle_Inflate(run_t * run,size_t off,size_t len)69 static void mangle_Inflate(run_t* run, size_t off, size_t len) {
70 if (run->dynamicFileSz >= run->global->maxFileSz) {
71 return;
72 }
73 if (len > (run->global->maxFileSz - run->dynamicFileSz)) {
74 len = run->global->maxFileSz - run->dynamicFileSz;
75 }
76
77 run->dynamicFileSz += len;
78 mangle_Move(run, off, off + len, run->dynamicFileSz);
79 }
80
mangle_MemMove(run_t * run)81 static void mangle_MemMove(run_t* run) {
82 size_t off_from = util_rndGet(0, run->dynamicFileSz - 1);
83 size_t off_to = util_rndGet(0, run->dynamicFileSz - 1);
84 size_t len = util_rndGet(0, run->dynamicFileSz);
85
86 mangle_Move(run, off_from, off_to, len);
87 }
88
mangle_Byte(run_t * run)89 static void mangle_Byte(run_t* run) {
90 size_t off = util_rndGet(0, run->dynamicFileSz - 1);
91 run->dynamicFile[off] = (uint8_t)util_rnd64();
92 }
93
mangle_Bytes(run_t * run)94 static void mangle_Bytes(run_t* run) {
95 size_t off = util_rndGet(0, run->dynamicFileSz - 1);
96 uint32_t val = (uint32_t)util_rnd64();
97
98 /* Overwrite with random 2,3,4-byte values */
99 size_t toCopy = util_rndGet(2, 4);
100 mangle_Overwrite(run, (uint8_t*)&val, off, toCopy);
101 }
102
mangle_Bit(run_t * run)103 static void mangle_Bit(run_t* run) {
104 size_t off = util_rndGet(0, run->dynamicFileSz - 1);
105 run->dynamicFile[off] ^= (uint8_t)(1U << util_rndGet(0, 7));
106 }
107
mangle_DictionaryInsert(run_t * run)108 static void mangle_DictionaryInsert(run_t* run) {
109 if (run->global->dictionaryCnt == 0) {
110 mangle_Bit(run);
111 return;
112 }
113
114 uint64_t choice = util_rndGet(0, run->global->dictionaryCnt - 1);
115 struct strings_t* str = TAILQ_FIRST(&run->global->dictq);
116 for (uint64_t i = 0; i < choice; i++) {
117 str = TAILQ_NEXT(str, pointers);
118 }
119
120 size_t off = util_rndGet(0, run->dynamicFileSz - 1);
121 mangle_Inflate(run, off, str->len);
122 mangle_Move(run, off, off + str->len, str->len);
123 mangle_Overwrite(run, (uint8_t*)str->s, off, str->len);
124 }
125
mangle_Dictionary(run_t * run)126 static void mangle_Dictionary(run_t* run) {
127 if (run->global->dictionaryCnt == 0) {
128 mangle_Bit(run);
129 return;
130 }
131
132 size_t off = util_rndGet(0, run->dynamicFileSz - 1);
133
134 uint64_t choice = util_rndGet(0, run->global->dictionaryCnt - 1);
135 struct strings_t* str = TAILQ_FIRST(&run->global->dictq);
136 for (uint64_t i = 0; i < choice; i++) {
137 str = TAILQ_NEXT(str, pointers);
138 }
139
140 mangle_Overwrite(run, (uint8_t*)str->s, off, str->len);
141 }
142
mangle_Magic(run_t * run)143 static void mangle_Magic(run_t* run) {
144 static const struct {
145 const uint8_t val[8];
146 const size_t size;
147 } mangleMagicVals[] = {
148 /* 1B - No endianness */
149 {"\x00\x00\x00\x00\x00\x00\x00\x00", 1},
150 {"\x01\x00\x00\x00\x00\x00\x00\x00", 1},
151 {"\x02\x00\x00\x00\x00\x00\x00\x00", 1},
152 {"\x03\x00\x00\x00\x00\x00\x00\x00", 1},
153 {"\x04\x00\x00\x00\x00\x00\x00\x00", 1},
154 {"\x05\x00\x00\x00\x00\x00\x00\x00", 1},
155 {"\x06\x00\x00\x00\x00\x00\x00\x00", 1},
156 {"\x07\x00\x00\x00\x00\x00\x00\x00", 1},
157 {"\x08\x00\x00\x00\x00\x00\x00\x00", 1},
158 {"\x09\x00\x00\x00\x00\x00\x00\x00", 1},
159 {"\x0A\x00\x00\x00\x00\x00\x00\x00", 1},
160 {"\x0B\x00\x00\x00\x00\x00\x00\x00", 1},
161 {"\x0C\x00\x00\x00\x00\x00\x00\x00", 1},
162 {"\x0D\x00\x00\x00\x00\x00\x00\x00", 1},
163 {"\x0E\x00\x00\x00\x00\x00\x00\x00", 1},
164 {"\x0F\x00\x00\x00\x00\x00\x00\x00", 1},
165 {"\x10\x00\x00\x00\x00\x00\x00\x00", 1},
166 {"\x20\x00\x00\x00\x00\x00\x00\x00", 1},
167 {"\x40\x00\x00\x00\x00\x00\x00\x00", 1},
168 {"\x7E\x00\x00\x00\x00\x00\x00\x00", 1},
169 {"\x7F\x00\x00\x00\x00\x00\x00\x00", 1},
170 {"\x80\x00\x00\x00\x00\x00\x00\x00", 1},
171 {"\x81\x00\x00\x00\x00\x00\x00\x00", 1},
172 {"\xC0\x00\x00\x00\x00\x00\x00\x00", 1},
173 {"\xFE\x00\x00\x00\x00\x00\x00\x00", 1},
174 {"\xFF\x00\x00\x00\x00\x00\x00\x00", 1},
175 /* 2B - NE */
176 {"\x00\x00\x00\x00\x00\x00\x00\x00", 2},
177 {"\x01\x01\x00\x00\x00\x00\x00\x00", 2},
178 {"\x80\x80\x00\x00\x00\x00\x00\x00", 2},
179 {"\xFF\xFF\x00\x00\x00\x00\x00\x00", 2},
180 /* 2B - BE */
181 {"\x00\x01\x00\x00\x00\x00\x00\x00", 2},
182 {"\x00\x02\x00\x00\x00\x00\x00\x00", 2},
183 {"\x00\x03\x00\x00\x00\x00\x00\x00", 2},
184 {"\x00\x04\x00\x00\x00\x00\x00\x00", 2},
185 {"\x00\x05\x00\x00\x00\x00\x00\x00", 2},
186 {"\x00\x06\x00\x00\x00\x00\x00\x00", 2},
187 {"\x00\x07\x00\x00\x00\x00\x00\x00", 2},
188 {"\x00\x08\x00\x00\x00\x00\x00\x00", 2},
189 {"\x00\x09\x00\x00\x00\x00\x00\x00", 2},
190 {"\x00\x0A\x00\x00\x00\x00\x00\x00", 2},
191 {"\x00\x0B\x00\x00\x00\x00\x00\x00", 2},
192 {"\x00\x0C\x00\x00\x00\x00\x00\x00", 2},
193 {"\x00\x0D\x00\x00\x00\x00\x00\x00", 2},
194 {"\x00\x0E\x00\x00\x00\x00\x00\x00", 2},
195 {"\x00\x0F\x00\x00\x00\x00\x00\x00", 2},
196 {"\x00\x10\x00\x00\x00\x00\x00\x00", 2},
197 {"\x00\x20\x00\x00\x00\x00\x00\x00", 2},
198 {"\x00\x40\x00\x00\x00\x00\x00\x00", 2},
199 {"\x00\x7E\x00\x00\x00\x00\x00\x00", 2},
200 {"\x00\x7F\x00\x00\x00\x00\x00\x00", 2},
201 {"\x00\x80\x00\x00\x00\x00\x00\x00", 2},
202 {"\x00\x81\x00\x00\x00\x00\x00\x00", 2},
203 {"\x00\xC0\x00\x00\x00\x00\x00\x00", 2},
204 {"\x00\xFE\x00\x00\x00\x00\x00\x00", 2},
205 {"\x00\xFF\x00\x00\x00\x00\x00\x00", 2},
206 {"\x7E\xFF\x00\x00\x00\x00\x00\x00", 2},
207 {"\x7F\xFF\x00\x00\x00\x00\x00\x00", 2},
208 {"\x80\x00\x00\x00\x00\x00\x00\x00", 2},
209 {"\x80\x01\x00\x00\x00\x00\x00\x00", 2},
210 {"\xFF\xFE\x00\x00\x00\x00\x00\x00", 2},
211 /* 2B - LE */
212 {"\x00\x00\x00\x00\x00\x00\x00\x00", 2},
213 {"\x01\x00\x00\x00\x00\x00\x00\x00", 2},
214 {"\x02\x00\x00\x00\x00\x00\x00\x00", 2},
215 {"\x03\x00\x00\x00\x00\x00\x00\x00", 2},
216 {"\x04\x00\x00\x00\x00\x00\x00\x00", 2},
217 {"\x05\x00\x00\x00\x00\x00\x00\x00", 2},
218 {"\x06\x00\x00\x00\x00\x00\x00\x00", 2},
219 {"\x07\x00\x00\x00\x00\x00\x00\x00", 2},
220 {"\x08\x00\x00\x00\x00\x00\x00\x00", 2},
221 {"\x09\x00\x00\x00\x00\x00\x00\x00", 2},
222 {"\x0A\x00\x00\x00\x00\x00\x00\x00", 2},
223 {"\x0B\x00\x00\x00\x00\x00\x00\x00", 2},
224 {"\x0C\x00\x00\x00\x00\x00\x00\x00", 2},
225 {"\x0D\x00\x00\x00\x00\x00\x00\x00", 2},
226 {"\x0E\x00\x00\x00\x00\x00\x00\x00", 2},
227 {"\x0F\x00\x00\x00\x00\x00\x00\x00", 2},
228 {"\x10\x00\x00\x00\x00\x00\x00\x00", 2},
229 {"\x20\x00\x00\x00\x00\x00\x00\x00", 2},
230 {"\x40\x00\x00\x00\x00\x00\x00\x00", 2},
231 {"\x7E\x00\x00\x00\x00\x00\x00\x00", 2},
232 {"\x7F\x00\x00\x00\x00\x00\x00\x00", 2},
233 {"\x80\x00\x00\x00\x00\x00\x00\x00", 2},
234 {"\x81\x00\x00\x00\x00\x00\x00\x00", 2},
235 {"\xC0\x00\x00\x00\x00\x00\x00\x00", 2},
236 {"\xFE\x00\x00\x00\x00\x00\x00\x00", 2},
237 {"\xFF\x00\x00\x00\x00\x00\x00\x00", 2},
238 {"\xFF\x7E\x00\x00\x00\x00\x00\x00", 2},
239 {"\xFF\x7F\x00\x00\x00\x00\x00\x00", 2},
240 {"\x00\x80\x00\x00\x00\x00\x00\x00", 2},
241 {"\x01\x80\x00\x00\x00\x00\x00\x00", 2},
242 {"\xFE\xFF\x00\x00\x00\x00\x00\x00", 2},
243 /* 4B - NE */
244 {"\x00\x00\x00\x00\x00\x00\x00\x00", 4},
245 {"\x01\x01\x01\x01\x00\x00\x00\x00", 4},
246 {"\x80\x80\x80\x80\x00\x00\x00\x00", 4},
247 {"\xFF\xFF\xFF\xFF\x00\x00\x00\x00", 4},
248 /* 4B - BE */
249 {"\x00\x00\x00\x01\x00\x00\x00\x00", 4},
250 {"\x00\x00\x00\x02\x00\x00\x00\x00", 4},
251 {"\x00\x00\x00\x03\x00\x00\x00\x00", 4},
252 {"\x00\x00\x00\x04\x00\x00\x00\x00", 4},
253 {"\x00\x00\x00\x05\x00\x00\x00\x00", 4},
254 {"\x00\x00\x00\x06\x00\x00\x00\x00", 4},
255 {"\x00\x00\x00\x07\x00\x00\x00\x00", 4},
256 {"\x00\x00\x00\x08\x00\x00\x00\x00", 4},
257 {"\x00\x00\x00\x09\x00\x00\x00\x00", 4},
258 {"\x00\x00\x00\x0A\x00\x00\x00\x00", 4},
259 {"\x00\x00\x00\x0B\x00\x00\x00\x00", 4},
260 {"\x00\x00\x00\x0C\x00\x00\x00\x00", 4},
261 {"\x00\x00\x00\x0D\x00\x00\x00\x00", 4},
262 {"\x00\x00\x00\x0E\x00\x00\x00\x00", 4},
263 {"\x00\x00\x00\x0F\x00\x00\x00\x00", 4},
264 {"\x00\x00\x00\x10\x00\x00\x00\x00", 4},
265 {"\x00\x00\x00\x20\x00\x00\x00\x00", 4},
266 {"\x00\x00\x00\x40\x00\x00\x00\x00", 4},
267 {"\x00\x00\x00\x7E\x00\x00\x00\x00", 4},
268 {"\x00\x00\x00\x7F\x00\x00\x00\x00", 4},
269 {"\x00\x00\x00\x80\x00\x00\x00\x00", 4},
270 {"\x00\x00\x00\x81\x00\x00\x00\x00", 4},
271 {"\x00\x00\x00\xC0\x00\x00\x00\x00", 4},
272 {"\x00\x00\x00\xFE\x00\x00\x00\x00", 4},
273 {"\x00\x00\x00\xFF\x00\x00\x00\x00", 4},
274 {"\x7E\xFF\xFF\xFF\x00\x00\x00\x00", 4},
275 {"\x7F\xFF\xFF\xFF\x00\x00\x00\x00", 4},
276 {"\x80\x00\x00\x00\x00\x00\x00\x00", 4},
277 {"\x80\x00\x00\x01\x00\x00\x00\x00", 4},
278 {"\xFF\xFF\xFF\xFE\x00\x00\x00\x00", 4},
279 /* 4B - LE */
280 {"\x00\x00\x00\x00\x00\x00\x00\x00", 4},
281 {"\x01\x00\x00\x00\x00\x00\x00\x00", 4},
282 {"\x02\x00\x00\x00\x00\x00\x00\x00", 4},
283 {"\x03\x00\x00\x00\x00\x00\x00\x00", 4},
284 {"\x04\x00\x00\x00\x00\x00\x00\x00", 4},
285 {"\x05\x00\x00\x00\x00\x00\x00\x00", 4},
286 {"\x06\x00\x00\x00\x00\x00\x00\x00", 4},
287 {"\x07\x00\x00\x00\x00\x00\x00\x00", 4},
288 {"\x08\x00\x00\x00\x00\x00\x00\x00", 4},
289 {"\x09\x00\x00\x00\x00\x00\x00\x00", 4},
290 {"\x0A\x00\x00\x00\x00\x00\x00\x00", 4},
291 {"\x0B\x00\x00\x00\x00\x00\x00\x00", 4},
292 {"\x0C\x00\x00\x00\x00\x00\x00\x00", 4},
293 {"\x0D\x00\x00\x00\x00\x00\x00\x00", 4},
294 {"\x0E\x00\x00\x00\x00\x00\x00\x00", 4},
295 {"\x0F\x00\x00\x00\x00\x00\x00\x00", 4},
296 {"\x10\x00\x00\x00\x00\x00\x00\x00", 4},
297 {"\x20\x00\x00\x00\x00\x00\x00\x00", 4},
298 {"\x40\x00\x00\x00\x00\x00\x00\x00", 4},
299 {"\x7E\x00\x00\x00\x00\x00\x00\x00", 4},
300 {"\x7F\x00\x00\x00\x00\x00\x00\x00", 4},
301 {"\x80\x00\x00\x00\x00\x00\x00\x00", 4},
302 {"\x81\x00\x00\x00\x00\x00\x00\x00", 4},
303 {"\xC0\x00\x00\x00\x00\x00\x00\x00", 4},
304 {"\xFE\x00\x00\x00\x00\x00\x00\x00", 4},
305 {"\xFF\x00\x00\x00\x00\x00\x00\x00", 4},
306 {"\xFF\xFF\xFF\x7E\x00\x00\x00\x00", 4},
307 {"\xFF\xFF\xFF\x7F\x00\x00\x00\x00", 4},
308 {"\x00\x00\x00\x80\x00\x00\x00\x00", 4},
309 {"\x01\x00\x00\x80\x00\x00\x00\x00", 4},
310 {"\xFE\xFF\xFF\xFF\x00\x00\x00\x00", 4},
311 /* 8B - NE */
312 {"\x00\x00\x00\x00\x00\x00\x00\x00", 8},
313 {"\x01\x01\x01\x01\x01\x01\x01\x01", 8},
314 {"\x80\x80\x80\x80\x80\x80\x80\x80", 8},
315 {"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8},
316 /* 8B - BE */
317 {"\x00\x00\x00\x00\x00\x00\x00\x01", 8},
318 {"\x00\x00\x00\x00\x00\x00\x00\x02", 8},
319 {"\x00\x00\x00\x00\x00\x00\x00\x03", 8},
320 {"\x00\x00\x00\x00\x00\x00\x00\x04", 8},
321 {"\x00\x00\x00\x00\x00\x00\x00\x05", 8},
322 {"\x00\x00\x00\x00\x00\x00\x00\x06", 8},
323 {"\x00\x00\x00\x00\x00\x00\x00\x07", 8},
324 {"\x00\x00\x00\x00\x00\x00\x00\x08", 8},
325 {"\x00\x00\x00\x00\x00\x00\x00\x09", 8},
326 {"\x00\x00\x00\x00\x00\x00\x00\x0A", 8},
327 {"\x00\x00\x00\x00\x00\x00\x00\x0B", 8},
328 {"\x00\x00\x00\x00\x00\x00\x00\x0C", 8},
329 {"\x00\x00\x00\x00\x00\x00\x00\x0D", 8},
330 {"\x00\x00\x00\x00\x00\x00\x00\x0E", 8},
331 {"\x00\x00\x00\x00\x00\x00\x00\x0F", 8},
332 {"\x00\x00\x00\x00\x00\x00\x00\x10", 8},
333 {"\x00\x00\x00\x00\x00\x00\x00\x20", 8},
334 {"\x00\x00\x00\x00\x00\x00\x00\x40", 8},
335 {"\x00\x00\x00\x00\x00\x00\x00\x7E", 8},
336 {"\x00\x00\x00\x00\x00\x00\x00\x7F", 8},
337 {"\x00\x00\x00\x00\x00\x00\x00\x80", 8},
338 {"\x00\x00\x00\x00\x00\x00\x00\x81", 8},
339 {"\x00\x00\x00\x00\x00\x00\x00\xC0", 8},
340 {"\x00\x00\x00\x00\x00\x00\x00\xFE", 8},
341 {"\x00\x00\x00\x00\x00\x00\x00\xFF", 8},
342 {"\x7E\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8},
343 {"\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8},
344 {"\x80\x00\x00\x00\x00\x00\x00\x00", 8},
345 {"\x80\x00\x00\x00\x00\x00\x00\x01", 8},
346 {"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFE", 8},
347 /* 8B - LE */
348 {"\x00\x00\x00\x00\x00\x00\x00\x00", 8},
349 {"\x01\x00\x00\x00\x00\x00\x00\x00", 8},
350 {"\x02\x00\x00\x00\x00\x00\x00\x00", 8},
351 {"\x03\x00\x00\x00\x00\x00\x00\x00", 8},
352 {"\x04\x00\x00\x00\x00\x00\x00\x00", 8},
353 {"\x05\x00\x00\x00\x00\x00\x00\x00", 8},
354 {"\x06\x00\x00\x00\x00\x00\x00\x00", 8},
355 {"\x07\x00\x00\x00\x00\x00\x00\x00", 8},
356 {"\x08\x00\x00\x00\x00\x00\x00\x00", 8},
357 {"\x09\x00\x00\x00\x00\x00\x00\x00", 8},
358 {"\x0A\x00\x00\x00\x00\x00\x00\x00", 8},
359 {"\x0B\x00\x00\x00\x00\x00\x00\x00", 8},
360 {"\x0C\x00\x00\x00\x00\x00\x00\x00", 8},
361 {"\x0D\x00\x00\x00\x00\x00\x00\x00", 8},
362 {"\x0E\x00\x00\x00\x00\x00\x00\x00", 8},
363 {"\x0F\x00\x00\x00\x00\x00\x00\x00", 8},
364 {"\x10\x00\x00\x00\x00\x00\x00\x00", 8},
365 {"\x20\x00\x00\x00\x00\x00\x00\x00", 8},
366 {"\x40\x00\x00\x00\x00\x00\x00\x00", 8},
367 {"\x7E\x00\x00\x00\x00\x00\x00\x00", 8},
368 {"\x7F\x00\x00\x00\x00\x00\x00\x00", 8},
369 {"\x80\x00\x00\x00\x00\x00\x00\x00", 8},
370 {"\x81\x00\x00\x00\x00\x00\x00\x00", 8},
371 {"\xC0\x00\x00\x00\x00\x00\x00\x00", 8},
372 {"\xFE\x00\x00\x00\x00\x00\x00\x00", 8},
373 {"\xFF\x00\x00\x00\x00\x00\x00\x00", 8},
374 {"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7E", 8},
375 {"\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F", 8},
376 {"\x00\x00\x00\x00\x00\x00\x00\x80", 8},
377 {"\x01\x00\x00\x00\x00\x00\x00\x80", 8},
378 {"\xFE\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8},
379 };
380
381 size_t off = util_rndGet(0, run->dynamicFileSz - 1);
382 uint64_t choice = util_rndGet(0, ARRAYSIZE(mangleMagicVals) - 1);
383 mangle_Overwrite(run, mangleMagicVals[choice].val, off, mangleMagicVals[choice].size);
384 }
385
mangle_MemSet(run_t * run)386 static void mangle_MemSet(run_t* run) {
387 size_t off = util_rndGet(0, run->dynamicFileSz - 1);
388 size_t sz = util_rndGet(1, run->dynamicFileSz - off);
389 int val = (int)util_rndGet(0, UINT8_MAX);
390
391 memset(&run->dynamicFile[off], val, sz);
392 }
393
mangle_Random(run_t * run)394 static void mangle_Random(run_t* run) {
395 size_t off = util_rndGet(0, run->dynamicFileSz - 1);
396 size_t len = util_rndGet(1, run->dynamicFileSz - off);
397 util_rndBuf(&run->dynamicFile[off], len);
398 }
399
mangle_AddSub(run_t * run)400 static void mangle_AddSub(run_t* run) {
401 size_t off = util_rndGet(0, run->dynamicFileSz - 1);
402
403 /* 1,2,4,8 */
404 uint64_t varLen = 1U << util_rndGet(0, 3);
405 if ((run->dynamicFileSz - off) < varLen) {
406 varLen = 1;
407 }
408
409 int delta = (int)util_rndGet(0, 8192);
410 delta -= 4096;
411
412 switch (varLen) {
413 case 1: {
414 run->dynamicFile[off] += delta;
415 return;
416 break;
417 }
418 case 2: {
419 int16_t val;
420 memcpy(&val, &run->dynamicFile[off], sizeof(val));
421 if (util_rnd64() & 0x1) {
422 val += delta;
423 } else {
424 /* Foreign endianess */
425 val = __builtin_bswap16(val);
426 val += delta;
427 val = __builtin_bswap16(val);
428 }
429 mangle_Overwrite(run, (uint8_t*)&val, off, varLen);
430 return;
431 break;
432 }
433 case 4: {
434 int32_t val;
435 memcpy(&val, &run->dynamicFile[off], sizeof(val));
436 if (util_rnd64() & 0x1) {
437 val += delta;
438 } else {
439 /* Foreign endianess */
440 val = __builtin_bswap32(val);
441 val += delta;
442 val = __builtin_bswap32(val);
443 }
444 mangle_Overwrite(run, (uint8_t*)&val, off, varLen);
445 return;
446 break;
447 }
448 case 8: {
449 int64_t val;
450 memcpy(&val, &run->dynamicFile[off], sizeof(val));
451 if (util_rnd64() & 0x1) {
452 val += delta;
453 } else {
454 /* Foreign endianess */
455 val = __builtin_bswap64(val);
456 val += delta;
457 val = __builtin_bswap64(val);
458 }
459 mangle_Overwrite(run, (uint8_t*)&val, off, varLen);
460 return;
461 break;
462 }
463 default: {
464 LOG_F("Unknown variable length size: %" PRIu64, varLen);
465 break;
466 }
467 }
468 }
469
mangle_IncByte(run_t * run)470 static void mangle_IncByte(run_t* run) {
471 size_t off = util_rndGet(0, run->dynamicFileSz - 1);
472 run->dynamicFile[off] += (uint8_t)1UL;
473 }
474
mangle_DecByte(run_t * run)475 static void mangle_DecByte(run_t* run) {
476 size_t off = util_rndGet(0, run->dynamicFileSz - 1);
477 run->dynamicFile[off] -= (uint8_t)1UL;
478 }
479
mangle_NegByte(run_t * run)480 static void mangle_NegByte(run_t* run) {
481 size_t off = util_rndGet(0, run->dynamicFileSz - 1);
482 run->dynamicFile[off] = ~(run->dynamicFile[off]);
483 }
484
mangle_CloneByte(run_t * run)485 static void mangle_CloneByte(run_t* run) {
486 size_t off1 = util_rndGet(0, run->dynamicFileSz - 1);
487 size_t off2 = util_rndGet(0, run->dynamicFileSz - 1);
488
489 uint8_t tmp = run->dynamicFile[off1];
490 run->dynamicFile[off1] = run->dynamicFile[off2];
491 run->dynamicFile[off2] = tmp;
492 }
493
mangle_Resize(run_t * run)494 static void mangle_Resize(run_t* run) {
495 run->dynamicFileSz = util_rndGet(0, run->global->maxFileSz);
496 }
497
mangle_Expand(run_t * run)498 static void mangle_Expand(run_t* run) {
499 size_t off = util_rndGet(0, run->dynamicFileSz - 1);
500 size_t len = util_rndGet(1, run->dynamicFileSz - off);
501
502 mangle_Inflate(run, off, len);
503 mangle_Move(run, off, off + len, run->dynamicFileSz);
504 }
505
mangle_Shrink(run_t * run)506 static void mangle_Shrink(run_t* run) {
507 if (run->dynamicFileSz <= 1U) {
508 return;
509 }
510
511 size_t len = util_rndGet(1, run->dynamicFileSz - 1);
512 size_t off = util_rndGet(0, len);
513
514 mangle_Move(run, off + len, off, run->dynamicFileSz);
515 run->dynamicFileSz -= len;
516 }
517
mangle_InsertRnd(run_t * run)518 static void mangle_InsertRnd(run_t* run) {
519 size_t off = util_rndGet(0, run->dynamicFileSz - 1);
520 size_t len = util_rndGet(1, run->dynamicFileSz - off);
521
522 mangle_Inflate(run, off, len);
523 mangle_Move(run, off, off + len, run->dynamicFileSz);
524 util_rndBuf(&run->dynamicFile[off], len);
525 }
526
mangle_ASCIIVal(run_t * run)527 static void mangle_ASCIIVal(run_t* run) {
528 char buf[32];
529 snprintf(buf, sizeof(buf), "%" PRId64, (int64_t)util_rnd64());
530 size_t off = util_rndGet(0, run->dynamicFileSz - 1);
531
532 mangle_Overwrite(run, (uint8_t*)buf, off, strlen(buf));
533 }
534
mangle_mangleContent(run_t * run)535 void mangle_mangleContent(run_t* run) {
536 if (run->mutationsPerRun == 0U) {
537 return;
538 }
539
540 /* 20% chance to change the file size */
541 if ((util_rnd64() % 5) == 0) {
542 mangle_Resize(run);
543 }
544
545 /* No point in modifying it if its size is 0 */
546 if (run->dynamicFileSz == 0UL) {
547 return;
548 }
549
550 static void (*const mangleFuncs[])(run_t * run) = {
551 mangle_Byte,
552 mangle_Bit,
553 mangle_Bytes,
554 mangle_Magic,
555 mangle_IncByte,
556 mangle_DecByte,
557 mangle_NegByte,
558 mangle_AddSub,
559 mangle_Dictionary,
560 mangle_DictionaryInsert,
561 mangle_MemMove,
562 mangle_MemSet,
563 mangle_Random,
564 mangle_CloneByte,
565 mangle_Expand,
566 mangle_Shrink,
567 mangle_InsertRnd,
568 mangle_ASCIIVal,
569 };
570
571 /* Max number of stacked changes is 6 */
572 uint64_t changesCnt = util_rndGet(1, run->global->mutationsPerRun);
573
574 for (uint64_t x = 0; x < changesCnt; x++) {
575 uint64_t choice = util_rndGet(0, ARRAYSIZE(mangleFuncs) - 1);
576 mangleFuncs[choice](run);
577 }
578 }
579