• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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