1 /* Copyright 2021 Google LLC
2 Licensed under the Apache License, Version 2.0 (the "License");
3 you may not use this file except in compliance with the License.
4 You may obtain a copy of the License at
5 http://www.apache.org/licenses/LICENSE-2.0
6 Unless required by applicable law or agreed to in writing, software
7 distributed under the License is distributed on an "AS IS" BASIS,
8 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
9 See the License for the specific language governing permissions and
10 limitations under the License.
11 */
12
13 #include "fuzz_header.h"
14
15 /*
16 * Targets "extract_addresses"
17 */
FuzzExtractTheAddress(const uint8_t ** data2,size_t * size2)18 void FuzzExtractTheAddress(const uint8_t **data2, size_t *size2) {
19 const uint8_t *data = *data2;
20 size_t size = *size2;
21
22 char *new_name = NULL;
23 new_name = get_null_terminated(&data, &size);
24 pointer_arr[pointer_idx++] = (void*)new_name;
25
26 int is_sign = get_int(&data, &size);
27 int check_rebind = get_int(&data, &size);
28 int secure = get_int(&data, &size);
29
30 if (size > (sizeof(struct dns_header) +50)) {
31 char *new_data = malloc(size);
32 memset(new_data, 0, size);
33 memcpy(new_data, data, size);
34 pointer_arr[pointer_idx++] = (void*)new_data;
35
36 time_t now;
37 int doctored = 0;
38 extract_addresses((struct dns_header *)new_data, size, new_name, now, NULL, NULL, is_sign, check_rebind, 0, secure, &doctored);
39 }
40 }
41
42
43 /*
44 * Targets "answer_request"
45 */
FuzzAnswerTheRequest(const uint8_t ** data2,size_t * size2)46 void FuzzAnswerTheRequest(const uint8_t **data2, size_t *size2) {
47 const uint8_t *data = *data2;
48 size_t size = *size2;
49
50 struct in_addr local_addr;
51 struct in_addr local_netmask;
52 time_t now;
53
54 int i1 = get_int(&data, &size);
55 int i2 = get_int(&data, &size);
56 int i3 = get_int(&data, &size);
57
58 if (size > (sizeof(struct dns_header) +50)) {
59 char *new_data = malloc(size);
60 memset(new_data, 0, size);
61 memcpy(new_data, data, size);
62 pointer_arr[pointer_idx++] = (void*)new_data;
63
64 answer_request((struct dns_header *)new_data, new_data+size, size, local_addr, local_netmask, now, i1, i2, i3);
65 }
66
67 }
68
69 /*
70 * Targets "check_for_ignored_address"
71 */
FuzzIgnoredAddress(const uint8_t ** data2,size_t * size2)72 void FuzzIgnoredAddress(const uint8_t **data2, size_t *size2) {
73 const uint8_t *data = *data2;
74 size_t size = *size2;
75
76 if (size > (sizeof(struct dns_header) +50)) {
77 //return 0;
78 char *new_data = malloc(size);
79 memset(new_data, 0, size);
80 memcpy(new_data, data, size);
81 pointer_arr[pointer_idx++] = (void*)new_data;
82
83 check_for_ignored_address((struct dns_header *)new_data, size);
84 }
85 }
86
87 /*
88 * Targets "check_for_local_domain"
89 */
FuzzCheckLocalDomain(const uint8_t ** data2,size_t * size2)90 void FuzzCheckLocalDomain(const uint8_t **data2, size_t *size2) {
91 const uint8_t *data = *data2;
92 size_t size = *size2;
93
94
95 char *new_data = malloc(size+1);
96 memset(new_data, 0, size);
97 memcpy(new_data, data, size);
98 new_data[size] = '\0';
99 pointer_arr[pointer_idx++] = (void*)new_data;
100
101 time_t now;
102 check_for_local_domain(new_data, now);
103 }
104
105 /*
106 * Targets "extract_request"
107 */
FuzzExtractRequest(const uint8_t ** data2,size_t * size2)108 void FuzzExtractRequest(const uint8_t **data2, size_t *size2) {
109 const uint8_t *data = *data2;
110 size_t size = *size2;
111
112 char *new_name = NULL;
113 new_name = get_null_terminated(&data, &size);
114
115 if (new_name == NULL) {
116 return ;
117 }
118 pointer_arr[pointer_idx++] = (void*)new_name;
119
120 if (size > (sizeof(struct dns_header) +50)) {
121 char *new_data = malloc(size+1);
122 memset(new_data, 0, size);
123 memcpy(new_data, data, size);
124 new_data[size] = '\0';
125 pointer_arr[pointer_idx++] = (void*)new_data;
126
127 unsigned short typeb;
128 extract_request((struct dns_header *)new_data, size, new_name, &typeb);
129 }
130 }
131
132
133 /*
134 * Targets "in_arpa_name_2_addr"
135 */
FuzzArpaName2Addr(const uint8_t ** data2,size_t * size2)136 void FuzzArpaName2Addr(const uint8_t **data2, size_t *size2) {
137 const uint8_t *data = *data2;
138 size_t size = *size2;
139
140 char *new_name = NULL;
141 new_name = get_null_terminated(&data, &size);
142
143 if (new_name == NULL) {
144 return ;
145 }
146 pointer_arr[pointer_idx++] = (void*)new_name;
147 union all_addr addr;
148 in_arpa_name_2_addr(new_name, &addr);
149 return;
150 }
151
FuzzResizePacket(const uint8_t ** data2,size_t * size2)152 void FuzzResizePacket(const uint8_t **data2, size_t *size2) {
153 const uint8_t *data = *data2;
154 size_t size = *size2;
155
156 char *new_packet = malloc(50);
157
158 if (size > (sizeof(struct dns_header) + 50)) {
159 char *new_data = malloc(size+1);
160 memset(new_data, 0, size);
161 memcpy(new_data, data, size);
162 new_data[size] = '\0';
163 pointer_arr[pointer_idx++] = (void*)new_data;
164
165 resize_packet((struct dns_header *)new_data, size, (unsigned char*)new_packet, 50);
166 }
167 free(new_packet);
168 }
169
FuzzSetupReply(const uint8_t ** data2,size_t * size2)170 void FuzzSetupReply(const uint8_t **data2, size_t *size2) {
171 const uint8_t *data = *data2;
172 size_t size = *size2;
173
174 if (size > (sizeof(struct dns_header) + 50)) {
175 char *new_data = malloc(size+1);
176 memset(new_data, 0, size);
177 memcpy(new_data, data, size);
178 new_data[size] = '\0';
179 pointer_arr[pointer_idx++] = (void*)new_data;
180
181 setup_reply((struct dns_header *)new_data, 0, 0);
182 }
183 }
184
185
FuzzCheckForBogusWildcard(const uint8_t ** data2,size_t * size2)186 void FuzzCheckForBogusWildcard(const uint8_t **data2, size_t *size2) {
187 const uint8_t *data = *data2;
188 size_t size = *size2;
189
190 char *nname = gb_get_null_terminated(&data, &size);
191 if (nname == NULL) {
192 return;
193 }
194
195
196 if (size > (sizeof(struct dns_header) + 50)) {
197 char *new_data = malloc(size+1);
198 memset(new_data, 0, size);
199 memcpy(new_data, data, size);
200 new_data[size] = '\0';
201 pointer_arr[pointer_idx++] = (void*)new_data;
202
203 time_t now;
204 check_for_bogus_wildcard((struct dns_header *)new_data, size, nname, now);
205 }
206 }
207
208
209 /*
210 * Fuzzer entrypoint.
211 */
212
LLVMFuzzerTestOneInput(const uint8_t * data,size_t size)213 int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
214 daemon = NULL;
215 //printf("Running fuzzer\n");
216 if (size < 1) {
217 return 0;
218 }
219
220 // Initialize mini garbage collector
221 gb_init();
222
223 // Get a value we can use to decide which target to hit.
224 int i = (int)data[0];
225 data += 1;
226 size -= 1;
227
228 int succ = init_daemon(&data, &size);
229
230 if (succ == 0) {
231 cache_init();
232 blockdata_init();
233
234 //i = 7;
235 #define TS 9
236 if ((i % TS) == 0) {
237 FuzzExtractTheAddress(&data,&size);
238 }
239 else if ((i % TS) == 1) {
240 FuzzAnswerTheRequest(&data,&size);
241 }
242 else if ((i % TS) == 2) {
243 FuzzCheckLocalDomain(&data, &size);
244 }
245 else if ((i % TS) == 3) {
246 FuzzExtractRequest(&data, &size);
247 }
248 else if ((i % TS) == 4) {
249 FuzzArpaName2Addr(&data, &size);
250 }
251 else if ((i %TS) == 5) {
252 FuzzResizePacket(&data, &size);
253 }
254 else if ((i %TS) == 6) {
255 FuzzSetupReply(&data, &size);
256 }
257 else if ((i % TS) == 7) {
258 FuzzCheckForBogusWildcard(&data, &size);
259 }
260 else {
261 FuzzIgnoredAddress(&data, &size);
262 }
263 cache_start_insert();
264 fuzz_blockdata_cleanup();
265 }
266
267 // Free data in mini garbage collector.
268 gb_cleanup();
269
270 return 0;
271 }
272