diff options
Diffstat (limited to 'projects/dnsmasq/fuzz_rfc1035.c')
-rw-r--r-- | projects/dnsmasq/fuzz_rfc1035.c | 271 |
1 files changed, 271 insertions, 0 deletions
diff --git a/projects/dnsmasq/fuzz_rfc1035.c b/projects/dnsmasq/fuzz_rfc1035.c new file mode 100644 index 000000000..fb563f804 --- /dev/null +++ b/projects/dnsmasq/fuzz_rfc1035.c @@ -0,0 +1,271 @@ +/* Copyright 2021 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +#include "fuzz_header.h" + +/* + * Targets "extract_addresses" + */ +void FuzzExtractTheAddress(const uint8_t **data2, size_t *size2) { + const uint8_t *data = *data2; + size_t size = *size2; + + char *new_name = NULL; + new_name = get_null_terminated(&data, &size); + pointer_arr[pointer_idx++] = (void*)new_name; + + int is_sign = get_int(&data, &size); + int check_rebind = get_int(&data, &size); + int secure = get_int(&data, &size); + + if (size > (sizeof(struct dns_header) +50)) { + char *new_data = malloc(size); + memset(new_data, 0, size); + memcpy(new_data, data, size); + pointer_arr[pointer_idx++] = (void*)new_data; + + time_t now; + int doctored = 0; + extract_addresses((struct dns_header *)new_data, size, new_name, now, NULL, NULL, is_sign, check_rebind, 0, secure, &doctored); + } +} + + +/* + * Targets "answer_request" + */ +void FuzzAnswerTheRequest(const uint8_t **data2, size_t *size2) { + const uint8_t *data = *data2; + size_t size = *size2; + + struct in_addr local_addr; + struct in_addr local_netmask; + time_t now; + + int i1 = get_int(&data, &size); + int i2 = get_int(&data, &size); + int i3 = get_int(&data, &size); + + if (size > (sizeof(struct dns_header) +50)) { + char *new_data = malloc(size); + memset(new_data, 0, size); + memcpy(new_data, data, size); + pointer_arr[pointer_idx++] = (void*)new_data; + + answer_request((struct dns_header *)new_data, new_data+size, size, local_addr, local_netmask, now, i1, i2, i3); + } + +} + +/* + * Targets "check_for_ignored_address" + */ +void FuzzIgnoredAddress(const uint8_t **data2, size_t *size2) { + const uint8_t *data = *data2; + size_t size = *size2; + + if (size > (sizeof(struct dns_header) +50)) { + //return 0; + char *new_data = malloc(size); + memset(new_data, 0, size); + memcpy(new_data, data, size); + pointer_arr[pointer_idx++] = (void*)new_data; + + check_for_ignored_address((struct dns_header *)new_data, size); + } +} + +/* + * Targets "check_for_local_domain" + */ +void FuzzCheckLocalDomain(const uint8_t **data2, size_t *size2) { + const uint8_t *data = *data2; + size_t size = *size2; + + + char *new_data = malloc(size+1); + memset(new_data, 0, size); + memcpy(new_data, data, size); + new_data[size] = '\0'; + pointer_arr[pointer_idx++] = (void*)new_data; + + time_t now; + check_for_local_domain(new_data, now); +} + +/* + * Targets "extract_request" + */ +void FuzzExtractRequest(const uint8_t **data2, size_t *size2) { + const uint8_t *data = *data2; + size_t size = *size2; + + char *new_name = NULL; + new_name = get_null_terminated(&data, &size); + + if (new_name == NULL) { + return ; + } + pointer_arr[pointer_idx++] = (void*)new_name; + + if (size > (sizeof(struct dns_header) +50)) { + char *new_data = malloc(size+1); + memset(new_data, 0, size); + memcpy(new_data, data, size); + new_data[size] = '\0'; + pointer_arr[pointer_idx++] = (void*)new_data; + + unsigned short typeb; + extract_request((struct dns_header *)new_data, size, new_name, &typeb); + } +} + + +/* + * Targets "in_arpa_name_2_addr" + */ +void FuzzArpaName2Addr(const uint8_t **data2, size_t *size2) { + const uint8_t *data = *data2; + size_t size = *size2; + + char *new_name = NULL; + new_name = get_null_terminated(&data, &size); + + if (new_name == NULL) { + return ; + } + pointer_arr[pointer_idx++] = (void*)new_name; + union all_addr addr; + in_arpa_name_2_addr(new_name, &addr); + return; +} + +void FuzzResizePacket(const uint8_t **data2, size_t *size2) { + const uint8_t *data = *data2; + size_t size = *size2; + + char *new_packet = malloc(50); + + if (size > (sizeof(struct dns_header) + 50)) { + char *new_data = malloc(size+1); + memset(new_data, 0, size); + memcpy(new_data, data, size); + new_data[size] = '\0'; + pointer_arr[pointer_idx++] = (void*)new_data; + + resize_packet((struct dns_header *)new_data, size, (unsigned char*)new_packet, 50); + } + free(new_packet); +} + +void FuzzSetupReply(const uint8_t **data2, size_t *size2) { + const uint8_t *data = *data2; + size_t size = *size2; + + if (size > (sizeof(struct dns_header) + 50)) { + char *new_data = malloc(size+1); + memset(new_data, 0, size); + memcpy(new_data, data, size); + new_data[size] = '\0'; + pointer_arr[pointer_idx++] = (void*)new_data; + + setup_reply((struct dns_header *)new_data, 0, 0); + } +} + + +void FuzzCheckForBogusWildcard(const uint8_t **data2, size_t *size2) { + const uint8_t *data = *data2; + size_t size = *size2; + + char *nname = gb_get_null_terminated(&data, &size); + if (nname == NULL) { + return; + } + + + if (size > (sizeof(struct dns_header) + 50)) { + char *new_data = malloc(size+1); + memset(new_data, 0, size); + memcpy(new_data, data, size); + new_data[size] = '\0'; + pointer_arr[pointer_idx++] = (void*)new_data; + + time_t now; + check_for_bogus_wildcard((struct dns_header *)new_data, size, nname, now); + } +} + + +/* + * Fuzzer entrypoint. + */ + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + daemon = NULL; + //printf("Running fuzzer\n"); + if (size < 1) { + return 0; + } + + // Initialize mini garbage collector + gb_init(); + + // Get a value we can use to decide which target to hit. + int i = (int)data[0]; + data += 1; + size -= 1; + + int succ = init_daemon(&data, &size); + + if (succ == 0) { + cache_init(); + blockdata_init(); + + //i = 7; +#define TS 9 + if ((i % TS) == 0) { + FuzzExtractTheAddress(&data,&size); + } + else if ((i % TS) == 1) { + FuzzAnswerTheRequest(&data,&size); + } + else if ((i % TS) == 2) { + FuzzCheckLocalDomain(&data, &size); + } + else if ((i % TS) == 3) { + FuzzExtractRequest(&data, &size); + } + else if ((i % TS) == 4) { + FuzzArpaName2Addr(&data, &size); + } + else if ((i %TS) == 5) { + FuzzResizePacket(&data, &size); + } + else if ((i %TS) == 6) { + FuzzSetupReply(&data, &size); + } + else if ((i % TS) == 7) { + FuzzCheckForBogusWildcard(&data, &size); + } + else { + FuzzIgnoredAddress(&data, &size); + } + cache_start_insert(); + fuzz_blockdata_cleanup(); + } + + // Free data in mini garbage collector. + gb_cleanup(); + + return 0; +} |