oss-fuzz/projects/dnsmasq/fuzz_rfc1035.c

272 lines
6.5 KiB
C

/* 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 check_rebind = get_int(&data, &size);
int is_sign = 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, check_rebind, is_sign, 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;
}