openvpn: improve route fuzzer. (#6004)

This commit is contained in:
DavidKorczynski 2021-07-06 18:57:20 +01:00 committed by GitHub
parent b2cd6f498d
commit 336002acff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 176 additions and 40 deletions

View File

@ -75,3 +75,33 @@ extern "C" size_t fuzz_get_random_data(void *buf, size_t len) {
return ret_val;
}
// Simple garbage collector
#define GB_SIZE 100
void *pointer_arr[GB_SIZE];
static int pointer_idx = 0;
// If the garbage collector is used then this must be called as first thing
// during a fuzz run.
extern "C" void gb_init() {
pointer_idx = 0;
for (int i = 0; i < GB_SIZE; i++) {
pointer_arr[i] = NULL;
}
}
extern "C" void gb_cleanup() {
for(int i = 0; i < GB_SIZE; i++) {
if (pointer_arr[i] != NULL) {
free(pointer_arr[i]);
}
}
}
extern "C" char *gb_get_random_string() {
char *tmp = get_random_string();
pointer_arr[pointer_idx++] = (void*)tmp;
return tmp;
}

View File

@ -19,3 +19,7 @@ char *get_random_string();
int fuzz_randomizer_get_int(int min, int max);
size_t fuzz_get_random_data(void *buf, size_t len);
char *fuzz_random_get_string_max_length(int max_len);
void gb_init();
void gb_cleanup();
char *gb_get_random_string();

View File

@ -20,16 +20,17 @@ limitations under the License.
#include "fuzz_randomizer.h"
int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
fuzz_random_init(data, size);
struct route_option_list opt;
gb_init();
struct route_option_list *opt;
struct route_list rl;
// Initialisation
memset(&opt, 0, sizeof(opt));
int route_list_inited = 0;
int route_list_ipv6_inited = 0;
struct context c;
memset(&c, 0, sizeof(struct context));
@ -40,60 +41,161 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
init_verb_mute(&c, IVM_LEVEL_1);
init_options_dev(&c.options);
//options_postprocess(&c.options);
// options_postprocess(&c.options);
pre_setup(&c.options);
setenv_settings(c.es, &c.options);
ALLOC_OBJ_CLEAR_GC(c.options.connection_list, struct connection_list, &c.options.gc);
ALLOC_OBJ_CLEAR_GC(c.options.connection_list, struct connection_list,
&c.options.gc);
context_init_1(&c);
in_addr_t remote_host;
ssize_t default_metric;
char *tmp0 = get_random_string();
const char* remote_endpoint = tmp0;
// init
memset(&rl, 0, sizeof(struct route_list));
init_route_list(&rl, &opt, remote_endpoint,default_metric, remote_host, c.es, &c);
struct route_ipv6_list rl6;
struct route_ipv6_option_list *opt6;
// call 1
in_addr_t addr;
route_list_add_vpn_gateway(&rl, c.es, addr);
memset(&rl, 0, sizeof(rl));
memset(&rl6, 0, sizeof(rl6));
memset(&opt, 0, sizeof(opt));
memset(&opt6, 0, sizeof(opt6));
// call 2
struct route_ipv4 r;
struct route_option ro;
char *tmp1 = get_random_string();
char *tmp2 = get_random_string();
char *tmp3 = get_random_string();
char *tmp4 = get_random_string();
ro.network = tmp1;
ro.netmask = tmp2;
ro.gateway = tmp3;
ro.metric = tmp4;
ro.next = NULL;
opt6 = new_route_ipv6_option_list(&c.gc);
opt = new_route_option_list(&c.gc);
memset(&r, 0, sizeof(struct route_ipv4));
r.option = &ro;
r.flags = RT_DEFINED;
add_route(&r, NULL, 0, NULL, c.es, &c);
int total_to_fuzz = fuzz_randomizer_get_int(1, 20);
for (int i = 0; i < total_to_fuzz; i++) {
int selector = fuzz_randomizer_get_int(0, 13);
switch (selector) {
case 0:
if (route_list_inited == 0) {
const char *remote_endpoint = gb_get_random_string();
memset(&rl, 0, sizeof(struct route_list));
rl.flags = fuzz_randomizer_get_int(0, 0xffffff);
init_route_list(&rl, opt, remote_endpoint, default_metric, remote_host,
c.es, &c);
route_list_inited = 1;
}
break;
case 1:
if (route_list_inited) {
in_addr_t addr;
route_list_add_vpn_gateway(&rl, c.es, addr);
}
break;
case 2:
if (route_list_inited && route_list_ipv6_inited) {
struct tuntap tt;
memset(&tt, 0, sizeof(tt));
add_routes(&rl, &rl6, &tt, 0, c.es, &c);
}
break;
case 3:
if (route_list_inited) {
setenv_routes(c.es, &rl);
}
break;
case 4:
if (route_list_inited) {
struct route_ipv4 r;
struct route_option ro;
ro.network = gb_get_random_string();
ro.netmask = gb_get_random_string();
ro.gateway = gb_get_random_string();
ro.metric = gb_get_random_string();
ro.next = NULL;
gc_free(&rl.gc);
memset(&r, 0, sizeof(struct route_ipv4));
r.option = &ro;
r.flags = RT_DEFINED;
add_route(&r, NULL, 0, NULL, c.es, &c);
}
break;
case 5:
if (route_list_inited) {
char *s1 = get_random_string();
is_special_addr(s1);
free(s1);
}
break;
case 6:
if (route_list_ipv6_inited == 0) {
const char *remote_endpoint = gb_get_random_string();
memset(&rl, 0, sizeof(struct route_list));
struct in6_addr remote_host;
rl6.rgi6.flags = fuzz_randomizer_get_int(0, 0xffffff);
fuzz_get_random_data(&rl6.rgi6.hwaddr, 6);
char *t1 = gb_get_random_string();
if (strlen(t1) > 16) {
memcpy(rl6.rgi6.iface, t1, 16);
} else {
memcpy(rl6.rgi6.iface, t1, strlen(t1));
}
init_route_ipv6_list(&rl6, opt6, remote_endpoint, 0, &remote_host, c.es,
&c);
route_list_ipv6_inited = 1;
}
break;
case 7: {
unsigned int flags;
struct route_ipv6 r6;
struct tuntap tt;
memset(&tt, 0, sizeof(tt));
tt.actual_name = gb_get_random_string();
r6.iface = gb_get_random_string();
r6.flags = fuzz_randomizer_get_int(0, 0xfffff);
r6.netbits = fuzz_randomizer_get_int(0, 0xfffff);
r6.metric = fuzz_randomizer_get_int(0, 0xfffff);
r6.next = NULL;
add_route_ipv6(&r6, &tt, 0, c.es, &c);
} break;
case 8:
if (route_list_ipv6_inited && route_list_inited) {
delete_routes(&rl, &rl6, NULL, 0, c.es, &c);
route_list_ipv6_inited = 0;
route_list_inited = 0;
}
break;
case 9:
if (route_list_ipv6_inited) {
setenv_routes_ipv6(c.es, &rl6);
}
break;
case 10: {
add_route_ipv6_to_option_list(opt6, gb_get_random_string(),
gb_get_random_string(),
gb_get_random_string());
} break;
case 11: {
print_route_options(opt, M_NONFATAL);
} break;
case 12: {
add_route_to_option_list(opt, gb_get_random_string(),
gb_get_random_string(), gb_get_random_string(),
gb_get_random_string());
} break;
default:
break;
}
}
if (route_list_inited) {
gc_free(&rl.gc);
}
env_set_destroy(c.es);
context_gc_free(&c);
free(tmp0);
free(tmp1);
free(tmp2);
free(tmp3);
free(tmp4);
fuzz_random_destroy();
gb_cleanup();
return 0;
}