From 734b9fecfb9c71ae487535293b1d458fb42ce3ca Mon Sep 17 00:00:00 2001 From: Guido Vranken Date: Fri, 23 Jun 2017 15:43:13 +0200 Subject: [PATCH] Add route.c fuzzer --- src/openvpn/Makefile.am | 14 +- src/openvpn/fuzzer-route.c | 297 +++++++++++++++++++++++++++++++++++++ 2 files changed, 310 insertions(+), 1 deletion(-) create mode 100644 src/openvpn/fuzzer-route.c diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am index 83126a234..17ffd4e9b 100644 --- a/src/openvpn/Makefile.am +++ b/src/openvpn/Makefile.am @@ -124,7 +124,8 @@ libopenvpn_la_SOURCES += \ fuzzing.h fuzzing.c extra_PROGRAMS = \ - openvpn-fuzzer-base64 openvpn-fuzzer-base64-standalone + openvpn-fuzzer-base64 openvpn-fuzzer-base64-standalone \ + openvpn-fuzzer-route openvpn-fuzzer-route-standalone extradir = . fuzzer_sources = dummy.cpp fuzzer_cflags = \ @@ -151,7 +152,18 @@ openvpn_fuzzer_base64_SOURCES = $(fuzzer_sources) openvpn_fuzzer_base64_LDFLAGS = $(fuzzer_ldflags) openvpn_fuzzer_base64_CFLAGS = $(fuzzer_cflags) openvpn_fuzzer_base64_LDADD = $(fuzzer_ldadd) fuzzer-base64.o libFuzzer.a + +openvpn_fuzzer_route_SOURCES = $(fuzzer_sources) +openvpn_fuzzer_route_LDFLAGS = $(fuzzer_ldflags) +openvpn_fuzzer_route_CFLAGS = $(fuzzer_cflags) +openvpn_fuzzer_route_LDADD = $(fuzzer_ldadd) fuzzer-route.o libFuzzer.a + openvpn_fuzzer_base64_standalone_SOURCES = fuzzer-standalone-loader.c openvpn_fuzzer_base64_standalone_LDFLAGS = $(fuzzer_ldflags) openvpn_fuzzer_base64_standalone_CFLAGS = $(fuzzer_cflags) openvpn_fuzzer_base64_standalone_LDADD = $(fuzzer_ldadd) fuzzer-base64.o + +openvpn_fuzzer_route_standalone_SOURCES = fuzzer-standalone-loader.c +openvpn_fuzzer_route_standalone_LDFLAGS = $(fuzzer_ldflags) +openvpn_fuzzer_route_standalone_CFLAGS = $(fuzzer_cflags) +openvpn_fuzzer_route_standalone_LDADD = $(fuzzer_ldadd) fuzzer-route.o diff --git a/src/openvpn/fuzzer-route.c b/src/openvpn/fuzzer-route.c new file mode 100644 index 000000000..1c81900ef --- /dev/null +++ b/src/openvpn/fuzzer-route.c @@ -0,0 +1,297 @@ +#include "config.h" +#include "syshead.h" + +#include "fuzzing.h" +#include "route.h" +#include "buffer.h" + +static void serialize_route_bypass(struct route_bypass* bypass) +{ + test_undefined_memory(bypass->bypass, bypass->n_bypass * sizeof(bypass->bypass[0])); +} +static void serialize_route_special_addr(struct route_special_addr* spec) +{ + test_undefined_memory(&spec->flags, sizeof(spec->flags)); + test_undefined_memory(&spec->remote_endpoint, sizeof(spec->remote_endpoint)); + test_undefined_memory(&spec->remote_host, sizeof(spec->remote_host)); + test_undefined_memory(&spec->remote_host_local, sizeof(spec->remote_host_local)); + serialize_route_bypass(&spec->bypass); + test_undefined_memory(&spec->default_metric, sizeof(spec->default_metric)); +} + +static void serialize_route_gateway_address(struct route_gateway_address* gateway) +{ + test_undefined_memory(&gateway->addr, sizeof(gateway->addr)); + test_undefined_memory(&gateway->netmask, sizeof(gateway->netmask)); +} +static void serialize_route_gateway_info(struct route_gateway_info* rgi) +{ + int i; + test_undefined_memory(&rgi->flags, sizeof(rgi->flags)); + test_undefined_memory(&rgi->iface, sizeof(rgi->iface)); + test_undefined_memory(&rgi->hwaddr, sizeof(rgi->hwaddr)); + serialize_route_gateway_address(&(rgi->gateway)); + for (i = 0; i < rgi->n_addrs; i++) + { + serialize_route_gateway_address(&(rgi->addrs[i])); + } +} + +static void serialize_route_ipv4(struct route_ipv4* route) +{ + test_undefined_memory(&route->flags, sizeof(route->flags)); + test_undefined_memory(&route->network, sizeof(route->network)); + test_undefined_memory(&route->netmask, sizeof(route->netmask)); + test_undefined_memory(&route->gateway, sizeof(route->gateway)); + if (route->flags & RT_METRIC_DEFINED) + { + test_undefined_memory(&route->metric, sizeof(route->metric)); + } +} + +static void serialize_route_ipv4_list(struct route_ipv4* routes) +{ + while ( routes ) + { + serialize_route_ipv4(routes); + routes = routes->next; + } +} +static void serialize_route_list(struct route_list* rl) +{ + test_undefined_memory(&rl->iflags, sizeof(rl->iflags)); + serialize_route_special_addr(&rl->spec); + serialize_route_gateway_info(&rl->rgi); + test_undefined_memory(&rl->flags, sizeof(rl->flags)); + if ( rl->routes ) + { + serialize_route_ipv4_list(rl->routes); + } +} + +static void serialize_route_ipv6(struct route_ipv6* route) +{ + test_undefined_memory(&route->flags, sizeof(route->flags)); + test_undefined_memory(&route->network, sizeof(route->network)); + test_undefined_memory(&route->netbits, sizeof(route->netbits)); + test_undefined_memory(&route->gateway, sizeof(route->gateway)); + if (route->flags & RT_METRIC_DEFINED) + { + test_undefined_memory(&route->metric, sizeof(route->metric)); + } +} +static void serialize_route_ipv6_list(struct route_ipv6* routes) +{ + while ( routes ) + { + serialize_route_ipv6(routes); + routes = routes->next; + } +} + +static void serialize_route_ipv6_gateway_address(struct route_ipv6_gateway_address* gateway) +{ + test_undefined_memory(&gateway->addr_ipv6, sizeof(gateway->addr_ipv6)); + test_undefined_memory(&gateway->netbits_ipv6, sizeof(gateway->netbits_ipv6)); +} + +static void serialize_route_ipv6_gateway_info(struct route_ipv6_gateway_info* rgi) +{ + int i; + + test_undefined_memory(&rgi->flags, sizeof(rgi->flags)); + test_undefined_memory(&rgi->iface, sizeof(rgi->iface)); + test_undefined_memory(&rgi->hwaddr, sizeof(rgi->hwaddr)); + serialize_route_ipv6_gateway_address(&(rgi->gateway)); + for (i = 0; i < rgi->n_addrs; i++) + { + serialize_route_ipv6_gateway_address(&(rgi->addrs[i])); + } +} +static void serialize_route6_list(struct route_ipv6_list* rl6) +{ + test_undefined_memory(&rl6->iflags, sizeof(rl6->iflags)); + test_undefined_memory(&rl6->spec_flags, sizeof(rl6->spec_flags)); + test_undefined_memory(&rl6->remote_endpoint_ipv6, sizeof(rl6->remote_endpoint_ipv6)); + test_undefined_memory(&rl6->remote_host_ipv6, sizeof(rl6->remote_host_ipv6)); + test_undefined_memory(&rl6->default_metric, sizeof(rl6->default_metric)); + serialize_route_ipv6_gateway_info(&rl6->rgi6); + test_undefined_memory(&rl6->flags, sizeof(rl6->flags)); + if ( rl6->routes_ipv6 ) + { + serialize_route_ipv6_list(rl6->routes_ipv6); + } +} + +int LLVMFuzzerInitialize(int *argc, char ***argv) +{ + return 1; +} +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + struct buffer buf; + struct env_set* es = NULL; + struct route_list rl; + struct route_ipv6_list rl6; + struct route_option_list opt, *dest; + struct route_ipv6_option_list opt6; + struct gc_arena gc; + ssize_t choice, input_size, num_loops, i; + ssize_t netbits; + unsigned char data2[10240]; + char* remote_endpoint = NULL; + bool route_list_inited = false; + bool route_ipv6_list_inited = false; + + fuzzer_set_input((unsigned char*)data, size); + memset(&rl, 0, sizeof(rl)); + memset(&rl6, 0, sizeof(rl6)); + memset(&opt, 0, sizeof(opt)); + memset(&opt6, 0, sizeof(opt6)); + + gc = gc_new(); + + opt.gc = &gc; + opt6.gc = &gc; + add_route_to_option_list(&opt, "a", "b", "d", "c"); + + es = env_set_create(&gc); + + FUZZER_GET_INTEGER(num_loops, 3); + for (i = 0; i < num_loops; i++) + { + FUZZER_GET_INTEGER(choice, 0); + switch ( choice ) + { + case 0: + if ( route_list_inited == false ) + { + in_addr_t remote_host; + ssize_t default_metric; + FUZZER_GET_DATA(&remote_host, sizeof(remote_host)); + FUZZER_GET_DATA(&(opt.flags), sizeof(opt.flags)); + FUZZER_GET_STRING_GC(remote_endpoint, 32, &gc); + FUZZER_GET_INTEGER(default_metric, 1); + if ( init_route_list(&rl, &opt, remote_endpoint, default_metric, remote_host, es) ) + { + route_list_inited = true; + } + } + break; + case 1: + if ( route_list_inited == true ) + { + in_addr_t addr; + FUZZER_GET_DATA(&addr, sizeof(addr)); + route_list_add_vpn_gateway(&rl, es, addr); + } + case 2: + if ( route_list_inited == true ) + { + print_routes(&rl, 0); + } + break; + case 3: + dest = clone_route_option_list(&opt, &gc); + break; + case 4: + { + unsigned int flags; + struct route_ipv4 r; + struct route_option ro; + FUZZER_GET_STRING_GC(ro.network, 32, &gc); + FUZZER_GET_STRING_GC(ro.netmask, 32, &gc); + FUZZER_GET_STRING_GC(ro.gateway, 32, &gc); + FUZZER_GET_STRING_GC(ro.netmask, 32, &gc); + + FUZZER_GET_DATA(&flags, sizeof(flags)); + + FUZZER_GET_DATA(&r.flags, sizeof(r.flags)); + FUZZER_GET_DATA(&r.network, sizeof(r.network)); + FUZZER_GET_DATA(&r.netmask, sizeof(r.netmask)); + FUZZER_GET_DATA(&r.gateway, sizeof(r.gateway)); + FUZZER_GET_DATA(&r.metric, sizeof(r.metric)); + r.next = NULL; + r.option = &ro; + + add_route(&r, + NULL, + flags, + NULL, + es); + } + case 5: + { + unsigned int flags; + struct route_ipv6 r6; + struct tuntap tt; + + memset(&tt, 0, sizeof(tt)); + + //FUZZER_GET_STRING_GC(tt.actual_name, 32, &gc); + tt.actual_name = string_alloc("X", &gc); + + FUZZER_GET_DATA(&flags, sizeof(flags)); + + FUZZER_GET_DATA(&r6.flags, sizeof(r6.flags)); + FUZZER_GET_DATA(&r6.network, sizeof(r6.network)); + FUZZER_GET_DATA(&r6.gateway, sizeof(r6.gateway)); + FUZZER_GET_DATA(&r6.metric, sizeof(r6.metric)); + FUZZER_GET_DATA(&r6.netbits, sizeof(r6.netbits)); + FUZZER_GET_STRING_GC(r6.iface, 32, &gc); + /*r6.iface = string_alloc("Y", &gc);*/ + r6.next = NULL; + + add_route_ipv6(&r6, + &tt, + flags, + es); + } + break; + case 6: + if ( route_ipv6_list_inited == false ) + { + struct in6_addr remote_host; + char* remote_endpoint; + ssize_t default_metric; + + FUZZER_GET_STRING_GC(remote_endpoint, 32, &gc); + FUZZER_GET_DATA(&remote_host, sizeof(remote_host)); + FUZZER_GET_INTEGER(default_metric, 1); + + if ( init_route_ipv6_list(&rl6, &opt6, remote_endpoint, default_metric, &remote_host, es) ) + { + route_ipv6_list_inited = true; + } + } + break; + case 7: + if ( route_list_inited == true && route_ipv6_list_inited == true ) + { + unsigned int flags; + struct tuntap tt = {0}; + FUZZER_GET_DATA(&flags, sizeof(flags)); + FUZZER_GET_STRING_GC(tt.actual_name, 32, &gc); + //tt.actual_name = string_alloc("X", &gc); + add_routes(&rl, &rl6, &tt, flags, es); + } + break; + } + + } +cleanup: +#ifdef MSAN + if ( route_list_inited == true ) + { + serialize_route_list(&rl); + } + if ( route_ipv6_list_inited == true ) + { + serialize_route6_list(&rl6); + } +#endif + gc_free(&rl.gc); + getaddrinfo_free_all(); + gc_free(&gc); + return 0; +} -- 2.47.2