blob: de6f27e0791f6186626331a78d58070000e16fd3 [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>
29#include <stdlib.h>
30#include <string.h>
31#include <unistd.h>
32
33#include "log.h"
34#include "util.h"
35
36static void mangle_Byte(uint8_t * buf, size_t bufSz, size_t off)
37{
38 buf[off] = (uint8_t) util_rndGet(0, UINT8_MAX);
39 return;
40/* Ignore buffer size */
41 if (bufSz == 0) {
42 return;
43 }
44}
45
robert.swiecki@gmail.com457ca142015-02-22 14:59:34 +000046static void mangle_Bytes(uint8_t * buf, size_t bufSz, size_t off)
47{
48 uint32_t val = (uint32_t) util_rndGet(0, UINT32_MAX);
49
robert.swiecki@gmail.com12e75062015-02-22 15:01:21 +000050 /* Overwrite with random 2,3,4-byte values */
51 size_t toCopy = util_rndGet(2, 4);
robert.swiecki@gmail.com457ca142015-02-22 14:59:34 +000052 size_t maxToCopy = bufSz - off;
53 if (toCopy > maxToCopy) {
54 toCopy = maxToCopy;
55 }
56
57 memcpy(&buf[off], (uint8_t *) & val, toCopy);
58}
59
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +000060static void mangle_Bit(uint8_t * buf, size_t bufSz, size_t off)
61{
62 buf[off] ^= ((uint8_t) 1 << util_rndGet(0, 7));
63 return;
64/* Ignore buffer size */
65 if (bufSz == 0) {
66 return;
67 }
68}
69
70static void mangle_Magic(uint8_t * buf, size_t bufSz, size_t off)
71{
72/* *INDENT-OFF* */
73 const struct {
74 const uint8_t val[8];
75 const size_t size;
76 } mangleMagicVals[] = {
77 /* 1B - No endianess */
78 { "\x00\x00\x00\x00\x00\x00\x00\x00", 1},
79 { "\x01\x00\x00\x00\x00\x00\x00\x00", 1},
80 { "\x7F\x00\x00\x00\x00\x00\x00\x00", 1},
81 { "\x80\x00\x00\x00\x00\x00\x00\x00", 1},
82 { "\xFF\x00\x00\x00\x00\x00\x00\x00", 1},
83 /* 2B - NE */
84 { "\x00\x00\x00\x00\x00\x00\x00\x00", 2},
robert.swiecki@gmail.com1ba76192015-02-22 15:45:49 +000085 { "\x01\x01\x00\x00\x00\x00\x00\x00", 2},
86 { "\x80\x80\x00\x00\x00\x00\x00\x00", 2},
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +000087 { "\xFF\xFF\x00\x00\x00\x00\x00\x00", 2},
88 /* 2B - BE */
89 { "\x00\x01\x00\x00\x00\x00\x00\x00", 2},
90 { "\x7F\xFF\x00\x00\x00\x00\x00\x00", 2},
91 { "\x80\x00\x00\x00\x00\x00\x00\x00", 2},
92 /* 2B - LE */
93 { "\x00\x01\x00\x00\x00\x00\x00\x00", 2},
94 { "\xFF\x7F\x00\x00\x00\x00\x00\x00", 2},
95 { "\x00\x80\x00\x00\x00\x00\x00\x00", 2},
96 /* 4B - NE */
97 { "\x00\x00\x00\x00\x00\x00\x00\x00", 4},
robert.swiecki@gmail.com1ba76192015-02-22 15:45:49 +000098 { "\x01\x01\x01\x01\x00\x00\x00\x00", 4},
99 { "\x80\x80\x80\x80\x00\x00\x00\x00", 4},
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000100 { "\xFF\xFF\xFF\xFF\x00\x00\x00\x00", 4},
101 /* 4B - BE */
102 { "\x00\x00\x00\x01\x00\x00\x00\x00", 4},
103 { "\x7F\xFF\xFF\xFF\x00\x00\x00\x00", 4},
104 { "\x80\x00\x00\x00\x00\x00\x00\x00", 4},
105 /* 4B - LE */
106 { "\x01\x00\x00\x00\x00\x00\x00\x00", 4},
107 { "\xFF\xFF\xFF\x7F\x00\x00\x00\x00", 4},
108 { "\x00\x00\x00\x80\x00\x00\x00\x00", 4},
109 /* 8B - NE */
110 { "\x00\x00\x00\x00\x00\x00\x00\x00", 8},
robert.swiecki@gmail.com1ba76192015-02-22 15:45:49 +0000111 { "\x01\x01\x01\x01\x01\x01\x01\x01", 8},
112 { "\x80\x80\x80\x80\x80\x80\x80\x80", 8},
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000113 { "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8},
114 /* 8B - BE */
115 { "\x00\x00\x00\x00\x00\x00\x00\x01", 8},
116 { "\x7F\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8},
117 { "\x80\x00\x00\x00\x00\x00\x00\x00", 8},
118 /* 8B - LE */
119 { "\x01\x00\x00\x00\x00\x00\x00\x00", 8},
120 { "\xFF\xFF\xFF\xFF\xFF\xFF\xFF\x7F", 8},
121 { "\x00\x00\x00\x00\x00\x00\x00\x80", 8},
122 };
123/* *INDENT-ON* */
124
125 uint64_t choice = util_rndGet(0, ARRAYSIZE(mangleMagicVals) - 1);
126
127 size_t toCopy = mangleMagicVals[choice].size;
128 size_t maxToCopy = bufSz - off;
129 if (toCopy > maxToCopy) {
130 toCopy = maxToCopy;
131 }
132
133 memcpy(&buf[off], mangleMagicVals[choice].val, toCopy);
134}
135
136static void mangle_Shift(uint8_t * buf, size_t bufSz, size_t off)
137{
robert.swiecki@gmail.comb7779612015-02-22 14:51:17 +0000138 uint64_t mangleTo = util_rndGet(0, bufSz - 1);
robert.swiecki@gmail.com0a7eabe2015-02-22 14:47:45 +0000139
robert.swiecki@gmail.come8555c22015-02-22 14:49:22 +0000140 uint64_t mangleSzFrom = util_rndGet(1, bufSz - off);
141 uint64_t mangleSzTo = util_rndGet(1, bufSz - mangleTo);
robert.swiecki@gmail.com0a7eabe2015-02-22 14:47:45 +0000142 uint64_t mangleSz = mangleSzFrom < mangleSzTo ? mangleSzFrom : mangleSzTo;
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000143
144 memmove(&buf[mangleTo], &buf[off], mangleSz);
145}
146
147void mangle_mangleContent(honggfuzz_t * hfuzz, uint8_t * buf, size_t bufSz)
148{
149/* *INDENT-OFF* */
150 void (*const mangleFuncs[]) (uint8_t * buf, size_t bufSz, size_t off) = {
151 mangle_Byte,
robert.swiecki@gmail.com17ee6762015-02-22 15:19:31 +0000152 mangle_Byte,
153 mangle_Byte,
154 mangle_Byte,
155 mangle_Byte,
156 mangle_Byte,
157 mangle_Byte,
158 mangle_Byte,
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000159 mangle_Bit,
robert.swiecki@gmail.com17ee6762015-02-22 15:19:31 +0000160 mangle_Bit,
161 mangle_Bit,
162 mangle_Bit,
163 mangle_Bit,
164 mangle_Bit,
165 mangle_Bit,
166 mangle_Bit,
167 mangle_Bytes,
168 mangle_Bytes,
169 mangle_Magic,
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000170 mangle_Magic,
robert.swiecki@gmail.com83256582015-02-22 15:20:01 +0000171 mangle_Shift,
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000172 };
173/* *INDENT-ON* */
174
175 /*
176 * Minimal number of changes is 1
177 */
178 uint64_t changesCnt = bufSz * hfuzz->flipRate;
179 if (changesCnt == 0ULL) {
180 changesCnt = 1;
181 }
182 changesCnt = util_rndGet(1, changesCnt);
183
184 for (uint64_t x = 0; x < changesCnt; x++) {
robert.swiecki@gmail.com0a7eabe2015-02-22 14:47:45 +0000185 size_t offset = util_rndGet(0, bufSz - 1);
robert.swiecki@gmail.coma3e014e2015-02-22 14:33:46 +0000186 uint64_t choice = util_rndGet(0, ARRAYSIZE(mangleFuncs) - 1);
187 mangleFuncs[choice] (buf, bufSz, offset);
188 }
189}
190
191size_t mangle_resize(honggfuzz_t * hfuzz, uint8_t ** buf, size_t bufSz)
192{
193 if (!hfuzz) {
194 return 0LL;
195 }
196 if (!buf) {
197 return 0UL;
198 }
199 if (bufSz == 0) {
200 return 0UL;
201 }
202
203 return bufSz;
204}