From: Guido Vranken Date: Fri, 23 Jun 2017 14:00:07 +0000 (+0200) Subject: Add forward.c fuzzer X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4599e2edf658f2caeeee66ba35508f043ae18880;p=thirdparty%2Fopenvpn.git Add forward.c fuzzer --- diff --git a/src/openvpn/Makefile.am b/src/openvpn/Makefile.am index 219050080..99b9d0daf 100644 --- a/src/openvpn/Makefile.am +++ b/src/openvpn/Makefile.am @@ -126,7 +126,8 @@ libopenvpn_la_SOURCES += \ extra_PROGRAMS = \ openvpn-fuzzer-base64 openvpn-fuzzer-base64-standalone \ openvpn-fuzzer-route openvpn-fuzzer-route-standalone \ - openvpn-fuzzer-dhcp openvpn-fuzzer-dhcp-standalone + openvpn-fuzzer-dhcp openvpn-fuzzer-dhcp-standalone \ + openvpn-fuzzer-forward openvpn-fuzzer-forward-standalone extradir = . fuzzer_sources = dummy.cpp fuzzer_cflags = \ @@ -164,6 +165,11 @@ openvpn_fuzzer_dhcp_LDFLAGS = $(fuzzer_ldflags) openvpn_fuzzer_dhcp_CFLAGS = $(fuzzer_cflags) openvpn_fuzzer_dhcp_LDADD = $(fuzzer_ldadd) fuzzer-dhcp.o libFuzzer.a +openvpn_fuzzer_forward_SOURCES = $(fuzzer_sources) +openvpn_fuzzer_forward_LDFLAGS = $(fuzzer_ldflags) +openvpn_fuzzer_forward_CFLAGS = $(fuzzer_cflags) +openvpn_fuzzer_forward_LDADD = $(fuzzer_ldadd) fuzzer-forward.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) @@ -178,3 +184,8 @@ openvpn_fuzzer_dhcp_standalone_SOURCES = fuzzer-standalone-loader.c openvpn_fuzzer_dhcp_standalone_LDFLAGS = $(fuzzer_ldflags) openvpn_fuzzer_dhcp_standalone_CFLAGS = $(fuzzer_cflags) openvpn_fuzzer_dhcp_standalone_LDADD = $(fuzzer_ldadd) fuzzer-dhcp.o + +openvpn_fuzzer_forward_standalone_SOURCES = fuzzer-standalone-loader.c +openvpn_fuzzer_forward_standalone_LDFLAGS = $(fuzzer_ldflags) +openvpn_fuzzer_forward_standalone_CFLAGS = $(fuzzer_cflags) +openvpn_fuzzer_forward_standalone_LDADD = $(fuzzer_ldadd) fuzzer-forward.o diff --git a/src/openvpn/clinat.c b/src/openvpn/clinat.c index 633cec610..55ab463b6 100644 --- a/src/openvpn/clinat.c +++ b/src/openvpn/clinat.c @@ -50,6 +50,14 @@ add_entry(struct client_nat_option_list *dest, } } +/* Wrapper to add_entry for fuzzing */ +bool +client_nat_add_entry(struct client_nat_option_list *dest, + const struct client_nat_entry *e) +{ + return add_entry(dest, e); +} + void print_client_nat_list(const struct client_nat_option_list *list, int msglevel) { diff --git a/src/openvpn/clinat.h b/src/openvpn/clinat.h index e0cfad5b5..bf1c6231c 100644 --- a/src/openvpn/clinat.h +++ b/src/openvpn/clinat.h @@ -45,6 +45,8 @@ struct client_nat_option_list { struct client_nat_entry entries[MAX_CLIENT_NAT]; }; +bool client_nat_add_entry(struct client_nat_option_list *dest, const struct client_nat_entry *e); + struct client_nat_option_list *new_client_nat_list(struct gc_arena *gc); struct client_nat_option_list *clone_client_nat_option_list(const struct client_nat_option_list *src, struct gc_arena *gc); diff --git a/src/openvpn/forward.c b/src/openvpn/forward.c index 371ddca58..76b03fd3d 100644 --- a/src/openvpn/forward.c +++ b/src/openvpn/forward.c @@ -341,6 +341,7 @@ check_inactivity_timeout_dowork(struct context *c) int get_server_poll_remaining_time(struct event_timeout *server_poll_timeout) { + return -1; update_time(); int remaining = event_timeout_remaining(server_poll_timeout); return max_int(0, remaining); @@ -1209,7 +1210,8 @@ process_incoming_tun(struct context *c) &c->c2.n_trunc_pre_encrypt); #endif - encrypt_sign(c, true); + /* Disabled for fuzzing + * encrypt_sign(c, true); */ } else { diff --git a/src/openvpn/fuzzer-forward.c b/src/openvpn/fuzzer-forward.c new file mode 100644 index 000000000..faad3c291 --- /dev/null +++ b/src/openvpn/fuzzer-forward.c @@ -0,0 +1,158 @@ +#include "config.h" +#include "syshead.h" +#include "fuzzing.h" +#include "buffer.h" +#include "openvpn.h" +#include "forward.h" +#include "clinat.h" +#include "proto.h" +int LLVMFuzzerInitialize(int *argc, char ***argv) +{ + return 1; +} +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + struct gc_arena gc; + struct buffer buf; + struct client_nat_entry cne; + ssize_t num_loops, generic_ssizet; + unsigned int generic_uint, flags; + size_t n; + counter_type counter; + struct context ctx; + struct tuntap tuntap; + struct route_list route_list; + struct link_socket link_socket; + struct link_socket_actual to_link_addr; + + fuzzer_set_input((unsigned char*)data, size); + gc = gc_new(); + memset(&buf, 0, sizeof(buf)); + FUZZER_GET_INTEGER(generic_ssizet, 1); + switch ( generic_ssizet ) + { + case 0: + ctx.options.ce.mssfix = 0; + break; + case 1: + ctx.options.ce.mssfix = 1; + break; + } + + FUZZER_GET_INTEGER(generic_ssizet, 1); + switch ( generic_ssizet ) + { + case 0: + ctx.options.passtos = false; + break; + case 1: + ctx.options.passtos = true; + break; + } + + FUZZER_GET_INTEGER(generic_ssizet, 1); + switch ( generic_ssizet ) + { + case 0: + ctx.options.mode = MODE_POINT_TO_POINT; + break; + case 1: + ctx.options.mode = MODE_SERVER; + break; + } + + FUZZER_GET_INTEGER(generic_ssizet, 1); + switch ( generic_ssizet ) + { + case 0: + ctx.options.allow_recursive_routing= true; + break; + case 1: + ctx.options.allow_recursive_routing = false; + break; + } + + ctx.options.client_nat = new_client_nat_list(&gc); + + FUZZER_GET_INTEGER(num_loops, MAX_CLIENT_NAT); + for (n = 0; n < num_loops; n++) { + FUZZER_GET_DATA(&cne, sizeof(cne)); + client_nat_add_entry(ctx.options.client_nat, &cne); + } + + FUZZER_GET_INTEGER(generic_ssizet, 1); + switch ( generic_ssizet ) + { + case 0: + ctx.options.route_gateway_via_dhcp = false; + break; + case 1: + ctx.options.route_gateway_via_dhcp = true; + break; + } + + ctx.c1.tuntap = &tuntap; + FUZZER_GET_INTEGER(generic_ssizet, 3); + switch ( generic_ssizet ) + { + case 0: + tuntap.type = DEV_TYPE_UNDEF; + break; + case 1: + tuntap.type = DEV_TYPE_NULL; + break; + case 2: + tuntap.type = DEV_TYPE_TUN; + break; + case 3: + tuntap.type = DEV_TYPE_TAP; + break; + } + + ctx.c1.route_list = &route_list; + + ctx.c2.link_socket = &link_socket; + + ctx.c2.es = env_set_create(&gc); + + FUZZER_GET_DATA(&generic_uint, sizeof(generic_uint)); + ctx.c2.frame.link_mtu_dynamic = generic_uint; + FUZZER_GET_DATA(&generic_uint, sizeof(generic_uint)); + ctx.c2.frame.extra_frame = generic_uint; + FUZZER_GET_DATA(&generic_uint, sizeof(generic_uint)); + ctx.c2.frame.extra_tun = generic_uint; + + FUZZER_GET_DATA(&flags, sizeof(flags)); + + if ( fuzzer_get_current_size() == 0 ) { + goto cleanup; + } + buf = alloc_buf(fuzzer_get_current_size()); + + if ( buf_write(&buf, fuzzer_get_current_data(), fuzzer_get_current_size()) == false ) { + abort(); + } + + fuzzer_alter_buffer(&buf); + ctx.c2.buf = buf; + ctx.c2.log_rw = false; + + FUZZER_GET_INTEGER(generic_ssizet, 1); + switch ( generic_ssizet ) + { + case 0: + ctx.c2.to_link_addr = NULL; + break; + case 1: + FUZZER_GET_DATA(&to_link_addr, sizeof(to_link_addr)); + ctx.c2.to_link_addr = &to_link_addr; + break; + } + + process_incoming_tun(&ctx); +cleanup: + free_buf(&buf); + gc_free(&gc); + + return 0; +}