diff --git a/scripts/codegen/fuzzing_include_am.py b/scripts/codegen/fuzzing_include_am.py index 6e45c21926..a1ef101dc9 100755 --- a/scripts/codegen/fuzzing_include_am.py +++ b/scripts/codegen/fuzzing_include_am.py @@ -8,6 +8,7 @@ FUZZERS = """ extrainfo hsdescv2 http + http-connect iptsv2 microdesc vrs diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 8d2b562d89..5d8b1ca1c1 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -127,7 +127,6 @@ static int connection_ap_handshake_process_socks(entry_connection_t *conn); static int connection_ap_process_natd(entry_connection_t *conn); -static int connection_ap_process_http_connect(entry_connection_t *conn); static int connection_exit_connect_dir(edge_connection_t *exitconn); static int consider_plaintext_ports(entry_connection_t *conn, uint16_t port); static int connection_ap_supports_optimistic_data(const entry_connection_t *); @@ -1184,10 +1183,10 @@ consider_plaintext_ports(entry_connection_t *conn, uint16_t port) * See connection_ap_handshake_rewrite_and_attach()'s * documentation for arguments and return value. */ -int -connection_ap_rewrite_and_attach_if_allowed(entry_connection_t *conn, - origin_circuit_t *circ, - crypt_path_t *cpath) +MOCK_IMPL(int, +connection_ap_rewrite_and_attach_if_allowed,(entry_connection_t *conn, + origin_circuit_t *circ, + crypt_path_t *cpath)) { const or_options_t *options = get_options(); @@ -2362,7 +2361,7 @@ connection_ap_process_natd(entry_connection_t *conn) * connection's socks_request field and try to attach the connection. On * failure, send an HTTP reply, and mark the connection. */ -static int +STATIC int connection_ap_process_http_connect(entry_connection_t *conn) { if (BUG(ENTRY_TO_CONN(conn)->state != AP_CONN_STATE_HTTP_CONNECT_WAIT)) diff --git a/src/or/connection_edge.h b/src/or/connection_edge.h index 9987f88b85..10ad97be47 100644 --- a/src/or/connection_edge.h +++ b/src/or/connection_edge.h @@ -89,9 +89,10 @@ int connection_ap_process_transparent(entry_connection_t *conn); int address_is_invalid_destination(const char *address, int client); -int connection_ap_rewrite_and_attach_if_allowed(entry_connection_t *conn, - origin_circuit_t *circ, - crypt_path_t *cpath); +MOCK_DECL(int, connection_ap_rewrite_and_attach_if_allowed, + (entry_connection_t *conn, + origin_circuit_t *circ, + crypt_path_t *cpath)); int connection_ap_handshake_rewrite_and_attach(entry_connection_t *conn, origin_circuit_t *circ, crypt_path_t *cpath); @@ -187,6 +188,8 @@ typedef struct { STATIC void connection_ap_handshake_rewrite(entry_connection_t *conn, rewrite_result_t *out); + +STATIC int connection_ap_process_http_connect(entry_connection_t *conn); #endif #endif diff --git a/src/test/fuzz/fuzz_http_connect.c b/src/test/fuzz/fuzz_http_connect.c new file mode 100644 index 0000000000..68f58387ed --- /dev/null +++ b/src/test/fuzz/fuzz_http_connect.c @@ -0,0 +1,105 @@ +/* Copyright (c) 2016-2017, The Tor Project, Inc. */ +/* See LICENSE for licensing information */ + +#include "orconfig.h" + +#define BUFFERS_PRIVATE +#define CONNECTION_EDGE_PRIVATE + +#include "or.h" +#include "backtrace.h" +#include "buffers.h" +#include "config.h" +#include "connection.h" +#include "connection_edge.h" +#include "torlog.h" + +#include "fuzzing.h" + +static void +mock_connection_write_to_buf_impl_(const char *string, size_t len, + connection_t *conn, int compressed) +{ + log_debug(LD_GENERAL, "%sResponse:\n%u\nConnection: %p\n%s\n", + compressed ? "Compressed " : "", (unsigned)len, conn, string); +} + +static void +mock_connection_mark_unattached_ap_(entry_connection_t *conn, int endreason, + int line, const char *file) +{ + (void)conn; + (void)endreason; + (void)line; + (void)file; +} + +static int +mock_connection_ap_rewrite_and_attach_if_allowed(entry_connection_t *conn, + origin_circuit_t *circ, + crypt_path_t *cpath) +{ + (void)conn; + (void)circ; + (void)cpath; + return 0; +} + +int +fuzz_init(void) +{ + /* Set up fake response handler */ + MOCK(connection_write_to_buf_impl_, mock_connection_write_to_buf_impl_); + /* Set up the fake handler functions */ + MOCK(connection_mark_unattached_ap_, mock_connection_mark_unattached_ap_); + MOCK(connection_ap_rewrite_and_attach_if_allowed, + mock_connection_ap_rewrite_and_attach_if_allowed); + + return 0; +} + +int +fuzz_cleanup(void) +{ + UNMOCK(connection_write_to_buf_impl_); + UNMOCK(connection_mark_unattached_ap_); + UNMOCK(connection_ap_rewrite_and_attach_if_allowed); + return 0; +} + +int +fuzz_main(const uint8_t *stdin_buf, size_t data_size) +{ + entry_connection_t conn; + + /* Set up the fake connection */ + memset(&conn, 0, sizeof(conn)); + conn.edge_.base_.type = CONN_TYPE_AP; + conn.edge_.base_.state = AP_CONN_STATE_HTTP_CONNECT_WAIT; + conn.socks_request = tor_malloc_zero(sizeof(socks_request_t)); + conn.socks_request->listener_type = CONN_TYPE_AP_HTTP_CONNECT_LISTENER; + + conn.edge_.base_.inbuf = buf_new_with_data((char*)stdin_buf, data_size); + if (!conn.edge_.base_.inbuf) { + log_debug(LD_GENERAL, "Zero-Length-Input\n"); + goto done; + } + + /* Parse the headers */ + int rv = connection_ap_process_http_connect(&conn); + + /* TODO: check the output is correctly parsed based on the input */ + + log_debug(LD_GENERAL, "Result:\n%d\n", rv); + + goto done; + + done: + /* Reset. */ + socks_request_free(conn.socks_request); + buf_free(conn.edge_.base_.inbuf); + conn.edge_.base_.inbuf = NULL; + + return 0; +} + diff --git a/src/test/fuzz/include.am b/src/test/fuzz/include.am index 2961dab56f..f3a1aaac94 100644 --- a/src/test/fuzz/include.am +++ b/src/test/fuzz/include.am @@ -102,6 +102,14 @@ src_test_fuzz_fuzz_http_CFLAGS = $(FUZZING_CFLAGS) src_test_fuzz_fuzz_http_LDFLAGS = $(FUZZING_LDFLAG) src_test_fuzz_fuzz_http_LDADD = $(FUZZING_LIBS) +src_test_fuzz_fuzz_http_connect_SOURCES = \ + src/test/fuzz/fuzzing_common.c \ + src/test/fuzz/fuzz_http_connect.c +src_test_fuzz_fuzz_http_connect_CPPFLAGS = $(FUZZING_CPPFLAGS) +src_test_fuzz_fuzz_http_connect_CFLAGS = $(FUZZING_CFLAGS) +src_test_fuzz_fuzz_http_connect_LDFLAGS = $(FUZZING_LDFLAG) +src_test_fuzz_fuzz_http_connect_LDADD = $(FUZZING_LIBS) + src_test_fuzz_fuzz_iptsv2_SOURCES = \ src/test/fuzz/fuzzing_common.c \ src/test/fuzz/fuzz_iptsv2.c @@ -134,6 +142,7 @@ FUZZERS = \ src/test/fuzz/fuzz-extrainfo \ src/test/fuzz/fuzz-hsdescv2 \ src/test/fuzz/fuzz-http \ + src/test/fuzz/fuzz-http-connect \ src/test/fuzz/fuzz-iptsv2 \ src/test/fuzz/fuzz-microdesc \ src/test/fuzz/fuzz-vrs @@ -190,6 +199,13 @@ src_test_fuzz_lf_fuzz_http_CFLAGS = $(LIBFUZZER_CFLAGS) src_test_fuzz_lf_fuzz_http_LDFLAGS = $(LIBFUZZER_LDFLAG) src_test_fuzz_lf_fuzz_http_LDADD = $(LIBFUZZER_LIBS) +src_test_fuzz_lf_fuzz_http_connect_SOURCES = \ + $(src_test_fuzz_fuzz_http_connect_SOURCES) +src_test_fuzz_lf_fuzz_http_connect_CPPFLAGS = $(LIBFUZZER_CPPFLAGS) +src_test_fuzz_lf_fuzz_http_connect_CFLAGS = $(LIBFUZZER_CFLAGS) +src_test_fuzz_lf_fuzz_http_connect_LDFLAGS = $(LIBFUZZER_LDFLAG) +src_test_fuzz_lf_fuzz_http_connect_LDADD = $(LIBFUZZER_LIBS) + src_test_fuzz_lf_fuzz_iptsv2_SOURCES = \ $(src_test_fuzz_fuzz_iptsv2_SOURCES) src_test_fuzz_lf_fuzz_iptsv2_CPPFLAGS = $(LIBFUZZER_CPPFLAGS) @@ -219,6 +235,7 @@ LIBFUZZER_FUZZERS = \ src/test/fuzz/lf-fuzz-extrainfo \ src/test/fuzz/lf-fuzz-hsdescv2 \ src/test/fuzz/lf-fuzz-http \ + src/test/fuzz/lf-fuzz-http-connect \ src/test/fuzz/lf-fuzz-iptsv2 \ src/test/fuzz/lf-fuzz-microdesc \ src/test/fuzz/lf-fuzz-vrs @@ -265,6 +282,11 @@ src_test_fuzz_liboss_fuzz_http_a_SOURCES = \ src_test_fuzz_liboss_fuzz_http_a_CPPFLAGS = $(LIBOSS_FUZZ_CPPFLAGS) src_test_fuzz_liboss_fuzz_http_a_CFLAGS = $(LIBOSS_FUZZ_CFLAGS) +src_test_fuzz_liboss_fuzz_http_connect_a_SOURCES = \ + $(src_test_fuzz_fuzz_http_connect_SOURCES) +src_test_fuzz_liboss_fuzz_http_connect_a_CPPFLAGS = $(LIBOSS_FUZZ_CPPFLAGS) +src_test_fuzz_liboss_fuzz_http_connect_a_CFLAGS = $(LIBOSS_FUZZ_CFLAGS) + src_test_fuzz_liboss_fuzz_iptsv2_a_SOURCES = \ $(src_test_fuzz_fuzz_iptsv2_SOURCES) src_test_fuzz_liboss_fuzz_iptsv2_a_CPPFLAGS = $(LIBOSS_FUZZ_CPPFLAGS) @@ -288,6 +310,7 @@ OSS_FUZZ_FUZZERS = \ src/test/fuzz/liboss-fuzz-extrainfo.a \ src/test/fuzz/liboss-fuzz-hsdescv2.a \ src/test/fuzz/liboss-fuzz-http.a \ + src/test/fuzz/liboss-fuzz-http-connect.a \ src/test/fuzz/liboss-fuzz-iptsv2.a \ src/test/fuzz/liboss-fuzz-microdesc.a \ src/test/fuzz/liboss-fuzz-vrs.a