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