blob: 04ab9138e2d106d891ae0fb3756b947e8d3c9e5a [file] [log] [blame]
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +00001/*
2 *
3 * honggfuzz - buffer 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 "common.h"
26#include "mangle.h"
27
28#include <inttypes.h>
robert.swiecki@gmail.com173f5192015-02-23 00:06:47 +000029#include <math.h>
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +000030#include <stdlib.h>
31#include <string.h>
robert.swiecki@gmail.come7680522015-02-22 22:22:37 +000032#include <sys/mman.h>
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +000033#include <unistd.h>
34
35#include "log.h"
36#include "util.h"
37
robert.swiecki@gmail.com8c3e0f22015-02-22 16:32:16 +000038static void mangle_Overwrite(uint8_t * dst, const uint8_t * src, size_t dstSz, size_t off,
robert.swiecki@gmail.com1c555c72015-02-22 16:25:54 +000039 size_t sz)
40{
41 size_t maxToCopy = dstSz - off;
42 if (sz > maxToCopy) {
43 sz = maxToCopy;
44 }
45
robert.swiecki@gmail.com50e1f3b2015-02-23 17:32:11 +000046 memcpy(&dst[off], src, sz);
robert.swiecki@gmail.com1c555c72015-02-22 16:25:54 +000047}
48
robert.swiecki@gmail.com4f1124f2015-04-21 17:12:22 +000049static void mangle_Byte(honggfuzz_t * hfuzz, uint8_t * buf, size_t bufSz, size_t off)
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +000050{
51 buf[off] = (uint8_t) util_rndGet(0, UINT8_MAX);
52 return;
robert.swiecki@gmail.com4be26672015-03-05 03:36:50 +000053 /* Ignore buffer size */
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +000054 if (bufSz == 0) {
55 return;
56 }
robert.swiecki@gmail.com4f1124f2015-04-21 17:12:22 +000057 if (hfuzz == NULL) {
58 return;
59 }
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +000060}
61
robert.swiecki@gmail.com4f1124f2015-04-21 17:12:22 +000062static void mangle_Bytes(honggfuzz_t * hfuzz, uint8_t * buf, size_t bufSz, size_t off)
robert.swiecki@gmail.com457ca142015-02-22 14:59:34 +000063{
64 uint32_t val = (uint32_t) util_rndGet(0, UINT32_MAX);
65
robert.swiecki@gmail.com12e75062015-02-22 15:01:21 +000066 /* Overwrite with random 2,3,4-byte values */
67 size_t toCopy = util_rndGet(2, 4);
robert.swiecki@gmail.combcdeaea2015-02-23 17:36:54 +000068 mangle_Overwrite(buf, (uint8_t *) & val, bufSz, off, toCopy);
robert.swiecki@gmail.com4f1124f2015-04-21 17:12:22 +000069 if (hfuzz == NULL) {
70 return;
71 }
robert.swiecki@gmail.com457ca142015-02-22 14:59:34 +000072}
73
robert.swiecki@gmail.com4f1124f2015-04-21 17:12:22 +000074static void mangle_Bit(honggfuzz_t * hfuzz, uint8_t * buf, size_t bufSz, size_t off)
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +000075{
76 buf[off] ^= ((uint8_t) 1 << util_rndGet(0, 7));
77 return;
robert.swiecki@gmail.com4be26672015-03-05 03:36:50 +000078 /* Ignore buffer size */
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +000079 if (bufSz == 0) {
80 return;
81 }
robert.swiecki@gmail.com4f1124f2015-04-21 17:12:22 +000082 if (hfuzz == NULL) {
83 return;
84 }
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +000085}
86
robert.swiecki@gmail.com4f1124f2015-04-21 17:12:22 +000087static void mangle_Dictionary(honggfuzz_t * hfuzz, uint8_t * buf, size_t bufSz, size_t off)
88{
89 if (hfuzz->dictionaryCnt == 0) {
tlogic@gmail.com7b6d7ee2015-04-23 21:30:12 +000090 mangle_Bit(hfuzz, buf, bufSz, off);
91 return;
robert.swiecki@gmail.com4f1124f2015-04-21 17:12:22 +000092 }
93
94 uint64_t choice = util_rndGet(0, hfuzz->dictionaryCnt - 1);
95 mangle_Overwrite(buf, (uint8_t *) hfuzz->dictionary[choice], bufSz, off,
96 strlen(hfuzz->dictionary[choice]));
97 if (hfuzz == NULL) {
98 return;
99 }
100}
101
102static void mangle_Magic(honggfuzz_t * hfuzz, uint8_t * buf, size_t bufSz, size_t off)
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000103{
robert.swiecki@gmail.com4be26672015-03-05 03:36:50 +0000104 /* *INDENT-OFF* */
robert.swiecki@gmail.com3d928f12015-04-15 14:43:21 +0000105 static const struct {
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000106 const uint8_t val[8];
107 const size_t size;
108 } mangleMagicVals[] = {
109 /* 1B - No endianess */
110 { "\x00\x00\x00\x00\x00\x00\x00\x00", 1},
111 { "\x01\x00\x00\x00\x00\x00\x00\x00", 1},
robert.swiecki@gmail.combe554fb2015-02-23 00:31:53 +0000112 { "\x02\x00\x00\x00\x00\x00\x00\x00", 1},
113 { "\x03\x00\x00\x00\x00\x00\x00\x00", 1},
114 { "\x04\x00\x00\x00\x00\x00\x00\x00", 1},
robert.swiecki@gmail.com03e70392015-03-01 03:53:11 +0000115 { "\x7E\x00\x00\x00\x00\x00\x00\x00", 1},
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000116 { "\x7F\x00\x00\x00\x00\x00\x00\x00", 1},
117 { "\x80\x00\x00\x00\x00\x00\x00\x00", 1},
robert.swiecki@gmail.com395278b2015-02-28 22:48:53 +0000118 { "\x81\x00\x00\x00\x00\x00\x00\x00", 1},
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000119 { "\xFF\x00\x00\x00\x00\x00\x00\x00", 1},
120 /* 2B - NE */
121 { "\x00\x00\x00\x00\x00\x00\x00\x00", 2},
robert.swiecki@gmail.com1ba76192015-02-22 15:45:49 +0000122 { "\x01\x01\x00\x00\x00\x00\x00\x00", 2},
123 { "\x80\x80\x00\x00\x00\x00\x00\x00", 2},
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000124 { "\xFF\xFF\x00\x00\x00\x00\x00\x00", 2},
125 /* 2B - BE */
126 { "\x00\x01\x00\x00\x00\x00\x00\x00", 2},
robert.swiecki@gmail.combe554fb2015-02-23 00:31:53 +0000127 { "\x00\x02\x00\x00\x00\x00\x00\x00", 2},
128 { "\x00\x03\x00\x00\x00\x00\x00\x00", 2},
129 { "\x00\x04\x00\x00\x00\x00\x00\x00", 2},
robert.swiecki@gmail.com03e70392015-03-01 03:53:11 +0000130 { "\x7E\xFF\x00\x00\x00\x00\x00\x00", 2},
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000131 { "\x7F\xFF\x00\x00\x00\x00\x00\x00", 2},
132 { "\x80\x00\x00\x00\x00\x00\x00\x00", 2},
robert.swiecki@gmail.com395278b2015-02-28 22:48:53 +0000133 { "\x80\x01\x00\x00\x00\x00\x00\x00", 2},
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000134 /* 2B - LE */
robert.swiecki@gmail.combe554fb2015-02-23 00:31:53 +0000135 { "\x01\x00\x00\x00\x00\x00\x00\x00", 2},
136 { "\x02\x00\x00\x00\x00\x00\x00\x00", 2},
137 { "\x03\x00\x00\x00\x00\x00\x00\x00", 2},
138 { "\x04\x00\x00\x00\x00\x00\x00\x00", 2},
robert.swiecki@gmail.com03e70392015-03-01 03:53:11 +0000139 { "\xFF\x7E\x00\x00\x00\x00\x00\x00", 2},
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000140 { "\xFF\x7F\x00\x00\x00\x00\x00\x00", 2},
141 { "\x00\x80\x00\x00\x00\x00\x00\x00", 2},
robert.swiecki@gmail.com395278b2015-02-28 22:48:53 +0000142 { "\x01\x80\x00\x00\x00\x00\x00\x00", 2},
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000143 /* 4B - NE */
144 { "\x00\x00\x00\x00\x00\x00\x00\x00", 4},
robert.swiecki@gmail.com1ba76192015-02-22 15:45:49 +0000145 { "\x01\x01\x01\x01\x00\x00\x00\x00", 4},
146 { "\x80\x80\x80\x80\x00\x00\x00\x00", 4},
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000147 { "\xFF\xFF\xFF\xFF\x00\x00\x00\x00", 4},
148 /* 4B - BE */
149 { "\x00\x00\x00\x01\x00\x00\x00\x00", 4},
robert.swiecki@gmail.combe554fb2015-02-23 00:31:53 +0000150 { "\x00\x00\x00\x02\x00\x00\x00\x00", 4},
151 { "\x00\x00\x00\x03\x00\x00\x00\x00", 4},
152 { "\x00\x00\x00\x04\x00\x00\x00\x00", 4},
robert.swiecki@gmail.com03e70392015-03-01 03:53:11 +0000153 { "\x7E\xFF\xFF\xFF\x00\x00\x00\x00", 4},
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000154 { "\x7F\xFF\xFF\xFF\x00\x00\x00\x00", 4},
155 { "\x80\x00\x00\x00\x00\x00\x00\x00", 4},
robert.swiecki@gmail.com395278b2015-02-28 22:48:53 +0000156 { "\x80\x00\x00\x01\x00\x00\x00\x00", 4},
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000157 /* 4B - LE */
158 { "\x01\x00\x00\x00\x00\x00\x00\x00", 4},
robert.swiecki@gmail.combe554fb2015-02-23 00:31:53 +0000159 { "\x02\x00\x00\x00\x00\x00\x00\x00", 4},
160 { "\x03\x00\x00\x00\x00\x00\x00\x00", 4},
161 { "\x04\x00\x00\x00\x00\x00\x00\x00", 4},
robert.swiecki@gmail.com03e70392015-03-01 03:53:11 +0000162 { "\xFF\xFF\xFF\x7E\x00\x00\x00\x00", 4},
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000163 { "\xFF\xFF\xFF\x7F\x00\x00\x00\x00", 4},
164 { "\x00\x00\x00\x80\x00\x00\x00\x00", 4},
robert.swiecki@gmail.com395278b2015-02-28 22:48:53 +0000165 { "\x01\x00\x00\x80\x00\x00\x00\x00", 4},
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000166 /* 8B - NE */
167 { "\x00\x00\x00\x00\x00\x00\x00\x00", 8},
robert.swiecki@gmail.com1ba76192015-02-22 15:45:49 +0000168 { "\x01\x01\x01\x01\x01\x01\x01\x01", 8},
169 { "\x80\x80\x80\x80\x80\x80\x80\x80", 8},
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000170 { "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8},
171 /* 8B - BE */
172 { "\x00\x00\x00\x00\x00\x00\x00\x01", 8},
robert.swiecki@gmail.combe554fb2015-02-23 00:31:53 +0000173 { "\x00\x00\x00\x00\x00\x00\x00\x02", 8},
174 { "\x00\x00\x00\x00\x00\x00\x00\x03", 8},
175 { "\x00\x00\x00\x00\x00\x00\x00\x04", 8},
robert.swiecki@gmail.com03e70392015-03-01 03:53:11 +0000176 { "\x7E\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8},
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000177 { "\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8},
178 { "\x80\x00\x00\x00\x00\x00\x00\x00", 8},
robert.swiecki@gmail.com395278b2015-02-28 22:48:53 +0000179 { "\x80\x00\x00\x00\x00\x00\x00\x01", 8},
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000180 /* 8B - LE */
181 { "\x01\x00\x00\x00\x00\x00\x00\x00", 8},
robert.swiecki@gmail.combe554fb2015-02-23 00:31:53 +0000182 { "\x02\x00\x00\x00\x00\x00\x00\x00", 8},
183 { "\x03\x00\x00\x00\x00\x00\x00\x00", 8},
184 { "\x04\x00\x00\x00\x00\x00\x00\x00", 8},
robert.swiecki@gmail.com03e70392015-03-01 03:53:11 +0000185 { "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7E", 8},
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000186 { "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F", 8},
187 { "\x00\x00\x00\x00\x00\x00\x00\x80", 8},
robert.swiecki@gmail.com395278b2015-02-28 22:48:53 +0000188 { "\x01\x00\x00\x00\x00\x00\x00\x80", 8},
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000189 };
robert.swiecki@gmail.com4be26672015-03-05 03:36:50 +0000190 /* *INDENT-ON* */
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000191
192 uint64_t choice = util_rndGet(0, ARRAYSIZE(mangleMagicVals) - 1);
robert.swiecki@gmail.combcdeaea2015-02-23 17:36:54 +0000193 mangle_Overwrite(buf, mangleMagicVals[choice].val, bufSz, off, mangleMagicVals[choice].size);
robert.swiecki@gmail.com4f1124f2015-04-21 17:12:22 +0000194 if (hfuzz == NULL) {
195 return;
196 }
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000197}
198
robert.swiecki@gmail.com4f1124f2015-04-21 17:12:22 +0000199static void mangle_MemSet(honggfuzz_t * hfuzz, uint8_t * buf, size_t bufSz, size_t off)
robert.swiecki@gmail.com89cc38c2015-02-23 02:52:08 +0000200{
201 uint64_t sz = util_rndGet(1, bufSz - off);
202 int val = (int)util_rndGet(0, UINT8_MAX);
203
204 memset(&buf[off], val, sz);
robert.swiecki@gmail.com4f1124f2015-04-21 17:12:22 +0000205 if (hfuzz == NULL) {
206 return;
207 }
robert.swiecki@gmail.com89cc38c2015-02-23 02:52:08 +0000208}
209
robert.swiecki@gmail.com4f1124f2015-04-21 17:12:22 +0000210static void mangle_MemMove(honggfuzz_t * hfuzz, uint8_t * buf, size_t bufSz, size_t off)
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000211{
robert.swiecki@gmail.comb7779612015-02-22 14:51:17 +0000212 uint64_t mangleTo = util_rndGet(0, bufSz - 1);
robert.swiecki@gmail.com8c3e0f22015-02-22 16:32:16 +0000213 uint64_t mangleSzTo = bufSz - mangleTo;
robert.swiecki@gmail.com0a7eabe2015-02-22 14:47:45 +0000214
robert.swiecki@gmail.come8555c22015-02-22 14:49:22 +0000215 uint64_t mangleSzFrom = util_rndGet(1, bufSz - off);
robert.swiecki@gmail.com0a7eabe2015-02-22 14:47:45 +0000216 uint64_t mangleSz = mangleSzFrom < mangleSzTo ? mangleSzFrom : mangleSzTo;
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000217
218 memmove(&buf[mangleTo], &buf[off], mangleSz);
robert.swiecki@gmail.com4f1124f2015-04-21 17:12:22 +0000219 if (hfuzz == NULL) {
220 return;
221 }
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000222}
223
robert.swiecki@gmail.com4f1124f2015-04-21 17:12:22 +0000224static void mangle_Random(honggfuzz_t * hfuzz, uint8_t * buf, size_t bufSz, size_t off)
robert.swiecki@gmail.com89cc38c2015-02-23 02:52:08 +0000225{
226 uint64_t sz = util_rndGet(1, bufSz - off);
227 util_rndBuf(&buf[off], sz);
robert.swiecki@gmail.com4f1124f2015-04-21 17:12:22 +0000228 if (hfuzz == NULL) {
229 return;
230 }
robert.swiecki@gmail.com89cc38c2015-02-23 02:52:08 +0000231}
232
robert.swiecki@gmail.com4f1124f2015-04-21 17:12:22 +0000233static void mangle_AddSub(honggfuzz_t * hfuzz, uint8_t * buf, size_t bufSz, size_t off)
robert.swiecki@gmail.com549ff182015-02-28 22:38:00 +0000234{
235 /* 1,2,4 */
236 uint64_t varLen = 1ULL << util_rndGet(0, 2);
237 if ((bufSz - off) < varLen) {
robert.swiecki@gmail.com57197642015-03-01 15:39:30 +0000238 varLen = 1;
robert.swiecki@gmail.com549ff182015-02-28 22:38:00 +0000239 }
240
241 int delta = (int)util_rndGet(0, 64);
242 delta -= 32;
243
244 switch (varLen) {
245 case 1:
robert.swiecki@gmail.com62e34ae2015-03-05 03:39:32 +0000246 {
247 buf[off] += delta;
248 return;
249 break;
250 }
robert.swiecki@gmail.com549ff182015-02-28 22:38:00 +0000251 case 2:
robert.swiecki@gmail.com62e34ae2015-03-05 03:39:32 +0000252 {
253 uint16_t val = *((uint16_t *) & buf[off]);
254 if (util_rndGet(0, 1) == 0) {
255 /* BE */
256 val = util_ToFromBE16(val);
257 val += delta;
258 val = util_ToFromBE16(val);
259 } else {
260 /* LE */
261 val = util_ToFromLE16(val);
262 val += delta;
263 val = util_ToFromLE16(val);
264 }
265 mangle_Overwrite(buf, (uint8_t *) & val, bufSz, off, varLen);
266 return;
267 break;
robert.swiecki@gmail.com549ff182015-02-28 22:38:00 +0000268 }
269 case 4:
robert.swiecki@gmail.com62e34ae2015-03-05 03:39:32 +0000270 {
271 uint32_t val = *((uint32_t *) & buf[off]);
272 if (util_rndGet(0, 1) == 0) {
273 /* BE */
274 val = util_ToFromBE32(val);
275 val += delta;
276 val = util_ToFromBE32(val);
277 } else {
278 /* LE */
279 val = util_ToFromLE32(val);
280 val += delta;
281 val = util_ToFromLE32(val);
282 }
283 mangle_Overwrite(buf, (uint8_t *) & val, bufSz, off, varLen);
284 return;
285 break;
robert.swiecki@gmail.com549ff182015-02-28 22:38:00 +0000286 }
287 default:
robert.swiecki@gmail.com62e34ae2015-03-05 03:39:32 +0000288 {
289 LOGMSG(l_FATAL, "Unknown variable length size: %" PRId64, varLen);
290 break;
291 }
robert.swiecki@gmail.com549ff182015-02-28 22:38:00 +0000292 }
robert.swiecki@gmail.com4f1124f2015-04-21 17:12:22 +0000293 if (hfuzz == NULL) {
294 return;
295 }
robert.swiecki@gmail.com549ff182015-02-28 22:38:00 +0000296}
297
robert.swiecki@gmail.com4f1124f2015-04-21 17:12:22 +0000298static void mangle_IncByte(honggfuzz_t * hfuzz, uint8_t * buf, size_t bufSz, size_t off)
robert.swiecki@gmail.com78973ed2015-03-01 03:57:18 +0000299{
300 buf[off] += (uint8_t) 1UL;
301 return;
robert.swiecki@gmail.com4be26672015-03-05 03:36:50 +0000302 /* bufSz is unused */
robert.swiecki@gmail.com78973ed2015-03-01 03:57:18 +0000303 if (bufSz == 0) {
304 return;
305 }
robert.swiecki@gmail.com4f1124f2015-04-21 17:12:22 +0000306 if (hfuzz == NULL) {
307 return;
308 }
robert.swiecki@gmail.com78973ed2015-03-01 03:57:18 +0000309}
310
robert.swiecki@gmail.com4f1124f2015-04-21 17:12:22 +0000311static void mangle_DecByte(honggfuzz_t * hfuzz, uint8_t * buf, size_t bufSz, size_t off)
robert.swiecki@gmail.com78973ed2015-03-01 03:57:18 +0000312{
313 buf[off] -= (uint8_t) 1UL;
314 return;
robert.swiecki@gmail.com4be26672015-03-05 03:36:50 +0000315 /* bufSz is unused */
robert.swiecki@gmail.com78973ed2015-03-01 03:57:18 +0000316 if (bufSz == 0) {
317 return;
318 }
robert.swiecki@gmail.com4f1124f2015-04-21 17:12:22 +0000319 if (hfuzz == NULL) {
320 return;
321 }
robert.swiecki@gmail.com78973ed2015-03-01 03:57:18 +0000322}
323
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000324void mangle_mangleContent(honggfuzz_t * hfuzz, uint8_t * buf, size_t bufSz)
325{
robert.swiecki@gmail.com4be26672015-03-05 03:36:50 +0000326 /* *INDENT-OFF* */
robert.swiecki@gmail.com4f1124f2015-04-21 17:12:22 +0000327 void (*const mangleFuncs[]) (honggfuzz_t * hfuzz, uint8_t * buf, size_t bufSz, size_t off) = {
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000328 mangle_Byte,
robert.swiecki@gmail.com17ee6762015-02-22 15:19:31 +0000329 mangle_Byte,
330 mangle_Byte,
331 mangle_Byte,
332 mangle_Byte,
333 mangle_Byte,
334 mangle_Byte,
335 mangle_Byte,
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000336 mangle_Bit,
robert.swiecki@gmail.com17ee6762015-02-22 15:19:31 +0000337 mangle_Bit,
338 mangle_Bit,
339 mangle_Bit,
340 mangle_Bit,
341 mangle_Bit,
342 mangle_Bit,
343 mangle_Bit,
344 mangle_Bytes,
345 mangle_Bytes,
346 mangle_Magic,
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000347 mangle_Magic,
robert.swiecki@gmail.com87e72752015-03-03 16:15:59 +0000348 mangle_IncByte,
349 mangle_IncByte,
350 mangle_DecByte,
351 mangle_DecByte,
352 mangle_AddSub,
353 mangle_AddSub,
robert.swiecki@gmail.com4f1124f2015-04-21 17:12:22 +0000354 mangle_Dictionary,
355 mangle_Dictionary,
robert.swiecki@gmail.com89cc38c2015-02-23 02:52:08 +0000356 mangle_MemMove,
357 mangle_MemSet,
robert.swiecki@gmail.com50e1f3b2015-02-23 17:32:11 +0000358 mangle_Random,
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000359 };
robert.swiecki@gmail.com4be26672015-03-05 03:36:50 +0000360 /* *INDENT-ON* */
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000361
robert.swiecki@gmail.com457280e2015-02-28 23:59:18 +0000362 /* if -r 0.0 then just return */
363 if (hfuzz->flipRate == 0.0L) {
364 return;
365 }
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000366 /*
367 * Minimal number of changes is 1
368 */
369 uint64_t changesCnt = bufSz * hfuzz->flipRate;
370 if (changesCnt == 0ULL) {
371 changesCnt = 1;
372 }
373 changesCnt = util_rndGet(1, changesCnt);
374
375 for (uint64_t x = 0; x < changesCnt; x++) {
robert.swiecki@gmail.com0a7eabe2015-02-22 14:47:45 +0000376 size_t offset = util_rndGet(0, bufSz - 1);
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000377 uint64_t choice = util_rndGet(0, ARRAYSIZE(mangleFuncs) - 1);
robert.swiecki@gmail.com4f1124f2015-04-21 17:12:22 +0000378 mangleFuncs[choice] (hfuzz, buf, bufSz, offset);
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000379 }
380}
381
robert.swiecki@gmail.comf891cad2015-02-25 12:21:04 +0000382static double mangle_ExpDist(void)
robert.swiecki@gmail.com61b02a52015-02-23 01:14:18 +0000383{
robert.swiecki@gmail.comf891cad2015-02-25 12:21:04 +0000384 double rnd = (double)util_rndGet(1, UINT32_MAX) / (double)(UINT32_MAX);
robert.swiecki@gmail.comedbca382015-02-26 14:21:19 +0000385 return pow(rnd, 4.0L);
robert.swiecki@gmail.com61b02a52015-02-23 01:14:18 +0000386}
387
robert.swiecki@gmail.com173f5192015-02-23 00:06:47 +0000388/* Gauss-like distribution */
robert.swiecki@gmail.comace40862015-03-08 07:09:56 +0000389bool mangle_Resize(honggfuzz_t * hfuzz, uint8_t * buf, size_t * bufSz)
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000390{
robert.swiecki@gmail.com060a9dd2015-02-28 06:37:27 +0000391 const uint64_t chance_one_in_x = 5;
robert.swiecki@gmail.come7680522015-02-22 22:22:37 +0000392 if (util_rndGet(1, chance_one_in_x) != 1) {
393 return true;
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000394 }
robert.swiecki@gmail.comf891cad2015-02-25 12:21:04 +0000395 ssize_t newSz = *bufSz;
robert.swiecki@gmail.com1c246502015-02-25 13:47:27 +0000396 int delta = 0;
robert.swiecki@gmail.coma56173d2015-02-26 00:46:24 +0000397 unsigned int val = (unsigned int)util_rndGet(1, 64);
robert.swiecki@gmail.com1c246502015-02-25 13:47:27 +0000398 switch (val) {
robert.swiecki@gmail.coma56173d2015-02-26 00:46:24 +0000399 case 1 ... 16:
robert.swiecki@gmail.com1c246502015-02-25 13:47:27 +0000400 delta = -val;
401 break;
robert.swiecki@gmail.coma56173d2015-02-26 00:46:24 +0000402 case 17 ... 32:
403 delta = val - 16;
robert.swiecki@gmail.com1c246502015-02-25 13:47:27 +0000404 break;
robert.swiecki@gmail.coma56173d2015-02-26 00:46:24 +0000405 case 33 ... 48:
robert.swiecki@gmail.com1c246502015-02-25 13:47:27 +0000406 delta += (int)(mangle_ExpDist() * (double)((hfuzz->maxFileSz - *bufSz)));
407 break;
robert.swiecki@gmail.coma56173d2015-02-26 00:46:24 +0000408 case 49 ... 64:
robert.swiecki@gmail.com1c246502015-02-25 13:47:27 +0000409 delta -= (int)(mangle_ExpDist() * (double)(*bufSz));
410 break;
411 default:
412 LOGMSG(l_FATAL, "Random value out of scope %u", val);
413 break;
414 }
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000415
robert.swiecki@gmail.com1c246502015-02-25 13:47:27 +0000416 newSz += delta;
robert.swiecki@gmail.com173f5192015-02-23 00:06:47 +0000417
robert.swiecki@gmail.com59526032015-02-23 17:10:29 +0000418 if (newSz < 1) {
419 newSz = 1;
robert.swiecki@gmail.com173f5192015-02-23 00:06:47 +0000420 }
robert.swiecki@gmail.com1c246502015-02-25 13:47:27 +0000421 if (newSz > (ssize_t) hfuzz->maxFileSz) {
422 newSz = (ssize_t) hfuzz->maxFileSz;
robert.swiecki@gmail.com173f5192015-02-23 00:06:47 +0000423 }
424
robert.swiecki@gmail.comace40862015-03-08 07:09:56 +0000425 if ((size_t) newSz > *bufSz) {
426 util_rndBuf(&buf[*bufSz], newSz - *bufSz);
427 }
428
robert.swiecki@gmail.com1c246502015-02-25 13:47:27 +0000429 LOGMSG(l_DEBUG, "Current size: %zu, Maximal size: %zu, New Size: %zu, Delta: %d", *bufSz,
430 hfuzz->maxFileSz, newSz, delta);
robert.swiecki@gmail.com173f5192015-02-23 00:06:47 +0000431
robert.swiecki@gmail.com173f5192015-02-23 00:06:47 +0000432 *bufSz = (size_t) newSz;
robert.swiecki@gmail.come7680522015-02-22 22:22:37 +0000433 return true;
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000434}