diff --git a/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 b/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 index ac5852d8..deea421d 100644 --- a/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 +++ b/other/bootstrap_daemon/docker/tox-bootstrapd.sha256 @@ -1 +1 @@ -39a74721e1730757bdb96020acebe25bafb450a4298e4bc9556e3ad2d59260b1 /usr/local/bin/tox-bootstrapd +7c43e683316530c0e9c46df4e670465b887f2a0c0774ee1dc67e4b0e1ca20a35 /usr/local/bin/tox-bootstrapd diff --git a/testing/fuzzing/BUILD.bazel b/testing/fuzzing/BUILD.bazel index 87cd5725..1135a72c 100644 --- a/testing/fuzzing/BUILD.bazel +++ b/testing/fuzzing/BUILD.bazel @@ -1,19 +1,18 @@ load("@rules_cc//cc:defs.bzl", "cc_library") load("@rules_fuzzing//fuzzing:cc_defs.bzl", "cc_fuzz_test") -cc_library( - name = "fuzz_adapter", - srcs = ["fuzz_adapter.c"], - hdrs = ["fuzz_adapter.h"], - visibility = ["//c-toxcore:__subpackages__"], -) +package(features = ["layering_check"]) cc_library( name = "fuzz_support", srcs = ["fuzz_support.cc"], hdrs = ["fuzz_support.h"], visibility = ["//c-toxcore:__subpackages__"], - deps = ["//c-toxcore/toxcore:tox"], + deps = [ + "//c-toxcore/toxcore:crypto_core", + "//c-toxcore/toxcore:network", + "//c-toxcore/toxcore:tox", + ], ) cc_library( @@ -31,6 +30,9 @@ cc_fuzz_test( deps = [ ":fuzz_support", "//c-toxcore/toxcore:tox", + "//c-toxcore/toxcore:tox_dispatch", + "//c-toxcore/toxcore:tox_events", + "//c-toxcore/toxcore:util", ], ) diff --git a/testing/fuzzing/CMakeLists.txt b/testing/fuzzing/CMakeLists.txt index 588c1301..5c00c764 100644 --- a/testing/fuzzing/CMakeLists.txt +++ b/testing/fuzzing/CMakeLists.txt @@ -2,7 +2,7 @@ target_compile_definitions(toxcore_static PUBLIC "FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION") # Override network and random functions -add_library(fuzz_adapter fuzz_adapter.c fuzz_support.cc fuzz_support.h) +add_library(fuzz_support fuzz_support.cc fuzz_support.h) set(LIBFUZZER_LINKER_FLAGS) if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") @@ -13,14 +13,14 @@ endif() # Fuzzes the toxsave API add_executable(toxsave_fuzzer toxsave_harness.cc) -target_link_libraries(toxsave_fuzzer toxcore_static fuzz_adapter ${LIBFUZZER_LINKER_FLAGS}) +target_link_libraries(toxsave_fuzzer toxcore_static fuzz_support ${LIBFUZZER_LINKER_FLAGS}) # Fuzzes the bootstrap process add_executable(bootstrap_fuzzer bootstrap_harness.cc) -target_link_libraries(bootstrap_fuzzer toxcore_static fuzz_adapter ${LIBFUZZER_LINKER_FLAGS}) +target_link_libraries(bootstrap_fuzzer toxcore_static fuzz_support ${LIBFUZZER_LINKER_FLAGS}) add_executable(DHT_fuzz_test ../../toxcore/DHT_fuzz_test.cc) -target_link_libraries(DHT_fuzz_test toxcore_static fuzz_adapter ${LIBFUZZER_LINKER_FLAGS}) +target_link_libraries(DHT_fuzz_test toxcore_static fuzz_support ${LIBFUZZER_LINKER_FLAGS}) add_executable(tox_events_fuzz_test ../../toxcore/tox_events_fuzz_test.cc) -target_link_libraries(tox_events_fuzz_test toxcore_static fuzz_adapter ${LIBFUZZER_LINKER_FLAGS}) +target_link_libraries(tox_events_fuzz_test toxcore_static fuzz_support ${LIBFUZZER_LINKER_FLAGS}) diff --git a/testing/fuzzing/bootstrap_harness.cc b/testing/fuzzing/bootstrap_harness.cc index 49869e29..51ab52db 100644 --- a/testing/fuzzing/bootstrap_harness.cc +++ b/testing/fuzzing/bootstrap_harness.cc @@ -3,23 +3,124 @@ #include #include "../../toxcore/tox.h" +#include "../../toxcore/tox_dispatch.h" +#include "../../toxcore/tox_events.h" #include "../../toxcore/tox_private.h" -#include "fuzz_adapter.h" +#include "../../toxcore/tox_struct.h" +#include "../../toxcore/util.h" #include "fuzz_support.h" +namespace { + +void setup_callbacks(Tox_Dispatch *dispatch) +{ + tox_events_callback_conference_connected( + dispatch, [](Tox *tox, const Tox_Event_Conference_Connected *event, void *user_data) { + assert(event == nullptr); + }); + tox_events_callback_conference_connected( + dispatch, [](Tox *tox, const Tox_Event_Conference_Connected *event, void *user_data) { + assert(event == nullptr); + }); + tox_events_callback_conference_invite( + dispatch, [](Tox *tox, const Tox_Event_Conference_Invite *event, void *user_data) { + assert(event == nullptr); + }); + tox_events_callback_conference_message( + dispatch, [](Tox *tox, const Tox_Event_Conference_Message *event, void *user_data) { + assert(event == nullptr); + }); + tox_events_callback_conference_peer_list_changed(dispatch, + [](Tox *tox, const Tox_Event_Conference_Peer_List_Changed *event, void *user_data) { + assert(event == nullptr); + }); + tox_events_callback_conference_peer_name( + dispatch, [](Tox *tox, const Tox_Event_Conference_Peer_Name *event, void *user_data) { + assert(event == nullptr); + }); + tox_events_callback_conference_title( + dispatch, [](Tox *tox, const Tox_Event_Conference_Title *event, void *user_data) { + assert(event == nullptr); + }); + tox_events_callback_file_chunk_request( + dispatch, [](Tox *tox, const Tox_Event_File_Chunk_Request *event, void *user_data) { + assert(event == nullptr); + }); + tox_events_callback_file_recv( + dispatch, [](Tox *tox, const Tox_Event_File_Recv *event, void *user_data) { + assert(event == nullptr); + }); + tox_events_callback_file_recv_chunk( + dispatch, [](Tox *tox, const Tox_Event_File_Recv_Chunk *event, void *user_data) { + assert(event == nullptr); + }); + tox_events_callback_file_recv_control( + dispatch, [](Tox *tox, const Tox_Event_File_Recv_Control *event, void *user_data) { + assert(event == nullptr); + }); + tox_events_callback_friend_connection_status( + dispatch, [](Tox *tox, const Tox_Event_Friend_Connection_Status *event, void *user_data) { + assert(event == nullptr); + }); + tox_events_callback_friend_lossless_packet( + dispatch, [](Tox *tox, const Tox_Event_Friend_Lossless_Packet *event, void *user_data) { + assert(event == nullptr); + }); + tox_events_callback_friend_lossy_packet( + dispatch, [](Tox *tox, const Tox_Event_Friend_Lossy_Packet *event, void *user_data) { + assert(event == nullptr); + }); + tox_events_callback_friend_message( + dispatch, [](Tox *tox, const Tox_Event_Friend_Message *event, void *user_data) { + assert(event == nullptr); + }); + tox_events_callback_friend_name( + dispatch, [](Tox *tox, const Tox_Event_Friend_Name *event, void *user_data) { + assert(event == nullptr); + }); + tox_events_callback_friend_read_receipt( + dispatch, [](Tox *tox, const Tox_Event_Friend_Read_Receipt *event, void *user_data) { + assert(event == nullptr); + }); + tox_events_callback_friend_request( + dispatch, [](Tox *tox, const Tox_Event_Friend_Request *event, void *user_data) { + Tox_Err_Friend_Add err; + tox_friend_add_norequest(tox, tox_event_friend_request_get_public_key(event), &err); + assert(err == TOX_ERR_FRIEND_ADD_OK || err == TOX_ERR_FRIEND_ADD_OWN_KEY + || err == TOX_ERR_FRIEND_ADD_ALREADY_SENT + || err == TOX_ERR_FRIEND_ADD_BAD_CHECKSUM); + }); + tox_events_callback_friend_status( + dispatch, [](Tox *tox, const Tox_Event_Friend_Status *event, void *user_data) { + assert(event == nullptr); + }); + tox_events_callback_friend_status_message( + dispatch, [](Tox *tox, const Tox_Event_Friend_Status_Message *event, void *user_data) { + assert(event == nullptr); + }); + tox_events_callback_friend_typing( + dispatch, [](Tox *tox, const Tox_Event_Friend_Typing *event, void *user_data) { + assert(event == nullptr); + }); + tox_events_callback_self_connection_status( + dispatch, [](Tox *tox, const Tox_Event_Self_Connection_Status *event, void *user_data) { + assert(event == nullptr); + }); +} + +} + extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { - network_adapter_init(data, size); + Fuzz_Data input{data, size}; - uint64_t clock = 0; - auto sys = fuzz_system(clock); - assert(sys->mono_time_callback != nullptr); - assert(sys->mono_time_user_data != nullptr); + Fuzz_System sys(input); + assert(sys.rng != nullptr); Tox_Options *opts = tox_options_new(nullptr); assert(opts != nullptr); - tox_options_set_operating_system(opts, sys.get()); + tox_options_set_operating_system(opts, sys.sys.get()); Tox_Err_New error_new; Tox *tox = tox_new(opts, &error_new); @@ -34,19 +135,24 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) const bool success = tox_bootstrap(tox, "127.0.0.1", 12345, pub_key, nullptr); assert(success); - /* - * The iteration count here is a magic value in the literal sense, too small - * and coverage will be bad, too big and fuzzing will not be efficient. - * NOTE: This should be fine tuned after gathering some experience. - */ + tox_events_init(tox); - for (uint32_t i = 0; i < 50; ++i) { - tox_iterate(tox, nullptr); + Tox_Dispatch *dispatch = tox_dispatch_new(nullptr); + assert(dispatch != nullptr); + setup_callbacks(dispatch); + + while (input.size > 0) { + Tox_Err_Events_Iterate error_iterate; + Tox_Events *events = tox_events_iterate(tox, true, &error_iterate); + assert(tox_events_equal(events, events)); + tox_dispatch_invoke(dispatch, events, tox, nullptr); + tox_events_free(events); // Move the clock forward a decent amount so all the time-based checks // trigger more quickly. - clock += 200; + sys.clock += 200; } + tox_dispatch_free(dispatch); tox_kill(tox); return 0; // Non-zero return values are reserved for future use. } diff --git a/testing/fuzzing/fuzz_adapter.c b/testing/fuzzing/fuzz_adapter.c deleted file mode 100644 index 82fd6453..00000000 --- a/testing/fuzzing/fuzz_adapter.c +++ /dev/null @@ -1,89 +0,0 @@ -#include "fuzz_adapter.h" - -struct fuzz_buf { - /* Fuzz data buffer */ - const uint8_t *cur; - const uint8_t *end; -}; - -static struct fuzz_buf data; - -#include -#include -#include - - -void network_adapter_init(const uint8_t *buf, size_t length) -{ - data.cur = buf; - data.end = buf + length; -} - -ssize_t fuzz_sendto(int sockfd, const void *buf, size_t len, - int flags, const struct sockaddr *addr, - socklen_t addrlen) -{ - return len; -} - -ssize_t fuzz_send(int sockfd, const void *buf, size_t len, int flags) -{ - return len; -} - -static ssize_t recv_common(void *buf, size_t buf_len) -{ - if (data.cur + 2 >= data.end) { - return -1; - } - - uint16_t fuzz_len = (data.cur[0] << 8) | data.cur[1]; - data.cur += 2; - - size_t available = data.end - data.cur; - - size_t res = fuzz_len > available ? available : fuzz_len; - res = buf_len > res ? res : buf_len; - - memcpy(buf, data.cur, res); - data.cur += res; - - return res; -} - -ssize_t fuzz_recvfrom(int sockfd, void *buf, size_t len, - int flags, struct sockaddr *src_addr, - socklen_t *addr_len) -{ - if (src_addr && addr_len && (sizeof(struct sockaddr) <= *addr_len)) { - *src_addr = (struct sockaddr) { - 0 - }; - // Dummy Addr - src_addr->sa_family = AF_INET; - - // We want an AF_INET address with dummy values - struct sockaddr_in *addr_in = (struct sockaddr_in *)(void *)src_addr; - addr_in->sin_port = 12356; - addr_in->sin_addr.s_addr = INADDR_LOOPBACK + 1; - *addr_len = sizeof(struct sockaddr); - } - - return recv_common(buf, len); -} - -ssize_t fuzz_recv(int sockfd, void *buf, size_t len, int flags) -{ - return recv_common(buf, len); -} - -void fuzz_random_bytes(uint8_t *rnd, size_t length) -{ - // Amount of data is limited - size_t available = data.end - data.cur; - size_t bytes_read = length > available ? available : length; - // Initialize everything to make MSAN and others happy - memset(rnd, 0, length); - memcpy(rnd, data.cur, bytes_read); - data.cur += bytes_read; -} diff --git a/testing/fuzzing/fuzz_adapter.h b/testing/fuzzing/fuzz_adapter.h deleted file mode 100644 index 91fdbc76..00000000 --- a/testing/fuzzing/fuzz_adapter.h +++ /dev/null @@ -1,44 +0,0 @@ -/* SPDX-License-Identifier: GPL-3.0-or-later - * Copyright © 2021 The TokTok team. - */ - -#ifndef C_TOXCORE_TESTING_FUZZING_FUZZ_ADAPTER_H -#define C_TOXCORE_TESTING_FUZZING_FUZZ_ADAPTER_H - -#include -#include -#include - -#ifdef __cplusplus -extern "C" { -#endif - -/** - * @brief Init function for the fuzzing harness - * @param buf Begin of fuzz data - * @param length Length of buf - */ -void network_adapter_init(const uint8_t *buf, size_t length); - -/* The following functions intercept calls to standard network functions for fuzzing purposes and return data from the fuzz buffer. */ - -ssize_t fuzz_sendto(int sockfd, const void *buf, size_t len, - int flags, const struct sockaddr *addr, - socklen_t addrlen); - -ssize_t fuzz_send(int sockfd, const void *buf, size_t len, int flags); - -ssize_t fuzz_recvfrom(int sockfd, void *buf, size_t len, - int flags, struct sockaddr *src_addr, - socklen_t *addr_len); - -ssize_t fuzz_recv(int sockfd, void *buf, size_t len, int flags); - -/* The following functions intercept generation of random data */ -void fuzz_random_bytes(uint8_t *rnd, size_t length); - -#ifdef __cplusplus -} -#endif - -#endif // C_TOXCORE_TESTING_FUZZING_FUZZ_ADAPTER_H diff --git a/testing/fuzzing/fuzz_support.cc b/testing/fuzzing/fuzz_support.cc index b3e8ed32..21a3b310 100644 --- a/testing/fuzzing/fuzz_support.cc +++ b/testing/fuzzing/fuzz_support.cc @@ -4,18 +4,128 @@ #include "fuzz_support.h" +#include +#include + +#include +#include #include #include "../../toxcore/crypto_core.h" #include "../../toxcore/network.h" #include "../../toxcore/tox_private.h" -std::unique_ptr fuzz_system(uint64_t &clock) +// TODO(iphydf): Put this somewhere shared. +struct Network_Addr { + struct sockaddr_storage addr; + size_t size; +}; + +static int recv_common(Fuzz_Data &input, void *buf, size_t buf_len) { - auto sys = std::make_unique(); - sys->mono_time_callback = [](void *user_data) { return *static_cast(user_data); }; - sys->mono_time_user_data = &clock; - sys->rng = system_random(); // TODO(iphydf): Put fuzz_random here. - sys->ns = system_network(); // TODO(iphydf): Put fuzz_network here. - return sys; + if (input.size < 2) { + return -1; + } + + const size_t fuzz_len = (input.data[0] << 8) | input.data[1]; + input.data += 2; + input.size -= 2; + + const size_t res = std::min(buf_len, std::min(fuzz_len, input.size)); + + memcpy(buf, input.data, res); + input.data += res; + input.size -= res; + + return res; } + +static const Network_Funcs fuzz_network_funcs = { + .close = [](void *obj, int sock) { return 0; }, + .accept = [](void *obj, int sock) { return 2; }, + .bind = [](void *obj, int sock, const Network_Addr *addr) { return 0; }, + .listen = [](void *obj, int sock, int backlog) { return 0; }, + .recvbuf = + [](void *obj, int sock) { + // TODO(iphydf): Return something sensible here (from the fuzzer): number of + // bytes to be read from the socket. + return 0; + }, + .recv = + [](void *obj, int sock, uint8_t *buf, size_t len) { + // Receive data from the fuzzer. + return recv_common(static_cast(obj)->data, buf, len); + }, + .recvfrom = + [](void *obj, int sock, uint8_t *buf, size_t len, Network_Addr *addr) { + addr->addr = sockaddr_storage{}; + // Dummy Addr + addr->addr.ss_family = AF_INET; + + // We want an AF_INET address with dummy values + sockaddr_in *addr_in = reinterpret_cast(&addr->addr); + addr_in->sin_port = 12356; + addr_in->sin_addr.s_addr = INADDR_LOOPBACK + 1; + addr->size = sizeof(struct sockaddr); + + return recv_common(static_cast(obj)->data, buf, len); + }, + .send = + [](void *obj, int sock, const uint8_t *buf, size_t len) { + // Always succeed. + return static_cast(len); + }, + .sendto = + [](void *obj, int sock, const uint8_t *buf, size_t len, const Network_Addr *addr) { + // Always succeed. + return static_cast(len); + }, + .socket = [](void *obj, int domain, int type, int proto) { return 1; }, + .socket_nonblock = [](void *obj, int sock, bool nonblock) { return 0; }, + .getsockopt = + [](void *obj, int sock, int level, int optname, void *optval, size_t *optlen) { + memset(optval, 0, *optlen); + return 0; + }, + .setsockopt = [](void *obj, int sock, int level, int optname, const void *optval, + size_t optlen) { return 0; }, +}; + +static const Random_Funcs fuzz_random_funcs = { + .random_bytes = + [](void *obj, uint8_t *bytes, size_t length) { + Fuzz_System *sys = static_cast(obj); + // Amount of data is limited + const size_t available = sys->data.size; + const size_t bytes_read = std::min(length, available); + // Initialize everything to make MSAN and others happy + std::memset(bytes, 0, length); + std::memcpy(bytes, sys->data.data, bytes_read); + sys->data.data += bytes_read; + sys->data.size -= bytes_read; + }, + .random_uniform = + [](void *obj, uint32_t upper_bound) { + Fuzz_System *sys = static_cast(obj); + uint32_t randnum; + sys->rng->funcs->random_bytes( + sys, reinterpret_cast(&randnum), sizeof(randnum)); + return randnum % upper_bound; + }, +}; + +Fuzz_System::Fuzz_System(Fuzz_Data &input) + : clock(0) + , data(input) + , sys(std::make_unique()) + , ns(std::make_unique(Network{&fuzz_network_funcs, this})) + , rng(std::make_unique(Random{&fuzz_random_funcs, this})) +{ + sys->mono_time_callback + = [](void *user_data) { return static_cast(user_data)->clock; }; + sys->mono_time_user_data = this; + sys->ns = ns.get(); + sys->rng = rng.get(); +} + +Fuzz_System::~Fuzz_System() { } diff --git a/testing/fuzzing/fuzz_support.h b/testing/fuzzing/fuzz_support.h index a8a1d8da..b25a8076 100644 --- a/testing/fuzzing/fuzz_support.h +++ b/testing/fuzzing/fuzz_support.h @@ -97,6 +97,18 @@ void fuzz_select_target(const uint8_t *data, std::size_t size, Args &&... args) return fuzz_select_target(selector, input, std::forward(args)...); } -std::unique_ptr fuzz_system(uint64_t &clock); +struct Network; +struct Random; + +struct Fuzz_System { + uint64_t clock; + Fuzz_Data &data; + std::unique_ptr sys; + std::unique_ptr ns; + std::unique_ptr rng; + + Fuzz_System(Fuzz_Data &input); + ~Fuzz_System(); +}; #endif // C_TOXCORE_TESTING_FUZZING_FUZZ_SUPPORT_H diff --git a/testing/fuzzing/toxsave_harness.cc b/testing/fuzzing/toxsave_harness.cc index 068c9d9a..31b41a88 100644 --- a/testing/fuzzing/toxsave_harness.cc +++ b/testing/fuzzing/toxsave_harness.cc @@ -6,8 +6,9 @@ #include "../../toxcore/tox_private.h" #include "fuzz_support.h" -extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); -extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +namespace { + +void TestSaveDataLoading(Fuzz_Data &input) { Tox_Err_Options_New error_options; @@ -16,19 +17,21 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) assert(tox_options != nullptr); assert(error_options == TOX_ERR_OPTIONS_NEW_OK); - uint64_t clock = 0; - auto sys = fuzz_system(clock); - tox_options_set_operating_system(tox_options, sys.get()); + const size_t savedata_size = input.size; + CONSUME_OR_RETURN(const uint8_t *savedata, input, savedata_size); + + Fuzz_System sys(input); + tox_options_set_operating_system(tox_options, sys.sys.get()); // pass test data to Tox - tox_options_set_savedata_data(tox_options, data, size); + tox_options_set_savedata_data(tox_options, savedata, savedata_size); tox_options_set_savedata_type(tox_options, TOX_SAVEDATA_TYPE_TOX_SAVE); Tox *tox = tox_new(tox_options, nullptr); tox_options_free(tox_options); if (tox == nullptr) { // Tox save was invalid, we're finished here - return 0; + return; } // verify that the file can be saved again @@ -36,5 +39,14 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) tox_get_savedata(tox, new_savedata.data()); tox_kill(tox); +} + +} + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) +{ + Fuzz_Data input{data, size}; + TestSaveDataLoading(input); return 0; // Non-zero return values are reserved for future use. } diff --git a/toxcore/BUILD.bazel b/toxcore/BUILD.bazel index 0656707d..ffe2ff5f 100644 --- a/toxcore/BUILD.bazel +++ b/toxcore/BUILD.bazel @@ -64,7 +64,6 @@ cc_library( visibility = ["//c-toxcore:__subpackages__"], deps = [ ":ccompat", - "//c-toxcore/testing/fuzzing:fuzz_adapter", "@libsodium", ], ) @@ -136,7 +135,6 @@ cc_library( ], deps = [ ":ccompat", - "//c-toxcore/testing/fuzzing:fuzz_adapter", "@pthread", ], ) @@ -160,6 +158,7 @@ cc_library( "//c-toxcore/auto_tests:__pkg__", "//c-toxcore/other:__pkg__", "//c-toxcore/other/bootstrap_daemon:__pkg__", + "//c-toxcore/testing/fuzzing:__pkg__", "//c-toxcore/toxav:__pkg__", ], deps = [ @@ -178,6 +177,7 @@ cc_library( "//c-toxcore/auto_tests:__pkg__", "//c-toxcore/other:__pkg__", "//c-toxcore/other/bootstrap_daemon:__pkg__", + "//c-toxcore/testing/fuzzing:__pkg__", "//c-toxcore/toxav:__pkg__", ], deps = [ @@ -186,7 +186,6 @@ cc_library( ":logger", ":mono_time", ":util", - "//c-toxcore/testing/fuzzing:fuzz_adapter", "@libsodium", "@psocket", "@pthread", diff --git a/toxcore/ccompat.h b/toxcore/ccompat.h index 8cd2844c..9ea6739a 100644 --- a/toxcore/ccompat.h +++ b/toxcore/ccompat.h @@ -12,8 +12,6 @@ #include "attributes.h" -/* No declarations here. */ - //!TOKSTYLE- // Variable length arrays. diff --git a/toxcore/crypto_core.c b/toxcore/crypto_core.c index 5b360bdc..ccfda08d 100644 --- a/toxcore/crypto_core.c +++ b/toxcore/crypto_core.c @@ -40,12 +40,6 @@ #define ENC_SECRET_KEY_SIZE CRYPTO_SECRET_KEY_SIZE #endif -//!TOKSTYLE- -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -#include "../testing/fuzzing/fuzz_adapter.h" -#endif -//!TOKSTYLE+ - static_assert(CRYPTO_PUBLIC_KEY_SIZE == crypto_box_PUBLICKEYBYTES, "CRYPTO_PUBLIC_KEY_SIZE should be equal to crypto_box_PUBLICKEYBYTES"); static_assert(CRYPTO_SECRET_KEY_SIZE == crypto_box_SECRETKEYBYTES, @@ -122,38 +116,38 @@ static void crypto_free(uint8_t *ptr, size_t bytes) void crypto_memzero(void *data, size_t length) { -#ifndef VANILLA_NACL - sodium_memzero(data, length); -#else +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) || defined(VANILLA_NACL) memset(data, 0, length); +#else + sodium_memzero(data, length); #endif } bool crypto_memlock(void *data, size_t length) { -#ifndef VANILLA_NACL +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) || defined(VANILLA_NACL) + return false; +#else if (sodium_mlock(data, length) != 0) { return false; } return true; -#else - return false; #endif } bool crypto_memunlock(void *data, size_t length) { -#ifndef VANILLA_NACL +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) || defined(VANILLA_NACL) + return false; +#else if (sodium_munlock(data, length) != 0) { return false; } return true; -#else - return false; #endif } @@ -169,18 +163,26 @@ bool public_key_eq(const uint8_t *pk1, const uint8_t *pk2) bool crypto_sha512_eq(const uint8_t *cksum1, const uint8_t *cksum2) { -#ifndef VANILLA_NACL - return crypto_verify_64(cksum1, cksum2) == 0; -#else +#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) + // Hope that this is better for the fuzzer + return memcmp(cksum1, cksum2, CRYPTO_SHA512_SIZE) == 0; +#elif defined(VANILLA_NACL) const int lo = crypto_verify_32(cksum1, cksum2) == 0 ? 1 : 0; const int hi = crypto_verify_32(cksum1 + 8, cksum2 + 8) == 0 ? 1 : 0; return (lo & hi) == 1; +#else + return crypto_verify_64(cksum1, cksum2) == 0; #endif } bool crypto_sha256_eq(const uint8_t *cksum1, const uint8_t *cksum2) { +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + // Hope that this is better for the fuzzer + return memcmp(cksum1, cksum2, CRYPTO_SHA256_SIZE) == 0; +#else return crypto_verify_32(cksum1, cksum2) == 0; +#endif } uint8_t random_u08(const Random *rng) @@ -238,17 +240,19 @@ bool crypto_signature_verify(const uint8_t *signature, const uint8_t *message, u bool public_key_valid(const uint8_t *public_key) { - if (public_key[31] >= 128) { /* Last bit of key is always zero. */ - return false; - } - - return true; + /* Last bit of key is always zero. */ + return public_key[31] < 128; } int32_t encrypt_precompute(const uint8_t *public_key, const uint8_t *secret_key, uint8_t *shared_key) { +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + memcpy(shared_key, public_key, CRYPTO_SHARED_KEY_SIZE); + return 0; +#else return crypto_box_beforenm(shared_key, public_key, secret_key); +#endif } int32_t encrypt_data_symmetric(const uint8_t *shared_key, const uint8_t *nonce, @@ -450,11 +454,6 @@ void crypto_derive_public_key(uint8_t *public_key, const uint8_t *secret_key) crypto_scalarmult_curve25519_base(public_key, secret_key); } -void crypto_sha256(uint8_t *hash, const uint8_t *data, size_t length) -{ - crypto_hash_sha256(hash, data, length); -} - void new_hmac_key(const Random *rng, uint8_t *key) { random_bytes(rng, key, CRYPTO_HMAC_KEY_SIZE); @@ -472,31 +471,42 @@ bool crypto_hmac_verify(const uint8_t auth[CRYPTO_HMAC_SIZE], const uint8_t key[ return crypto_auth_verify(auth, data, length, key) == 0; } +void crypto_sha256(uint8_t *hash, const uint8_t *data, size_t length) +{ +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + memset(hash, 0, CRYPTO_SHA256_SIZE); + memcpy(hash, data, length < CRYPTO_SHA256_SIZE ? length : CRYPTO_SHA256_SIZE); +#else + crypto_hash_sha256(hash, data, length); +#endif +} + void crypto_sha512(uint8_t *hash, const uint8_t *data, size_t length) { +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + memset(hash, 0, CRYPTO_SHA512_SIZE); + memcpy(hash, data, length < CRYPTO_SHA512_SIZE ? length : CRYPTO_SHA512_SIZE); +#else crypto_hash_sha512(hash, data, length); +#endif } non_null() static void sys_random_bytes(void *obj, uint8_t *bytes, size_t length) { -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - fuzz_random_bytes(bytes, length); -#else randombytes(bytes, length); -#endif } non_null() static uint32_t sys_random_uniform(void *obj, uint32_t upper_bound) { -#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) || defined(VANILLA_NACL) +#ifdef VANILLA_NACL uint32_t randnum; sys_random_bytes(obj, (uint8_t *)&randnum, sizeof(randnum)); return randnum % upper_bound; #else return randombytes_uniform(upper_bound); -#endif // VANILLA_NACL +#endif } static const Random_Funcs system_random_funcs = { @@ -508,6 +518,11 @@ static const Random system_random_obj = {&system_random_funcs}; const Random *system_random(void) { +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + if ((true)) { + return nullptr; + } +#endif #ifndef VANILLA_NACL // It is safe to call this function more than once and from different // threads -- subsequent calls won't have any effects. @@ -515,7 +530,6 @@ const Random *system_random(void) return nullptr; } #endif - return &system_random_obj; } diff --git a/toxcore/network.c b/toxcore/network.c index 10252a9e..f9986f2e 100644 --- a/toxcore/network.c +++ b/toxcore/network.c @@ -97,12 +97,6 @@ #include "mono_time.h" #include "util.h" -//!TOKSTYLE- -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -#include "../testing/fuzzing/fuzz_adapter.h" -#endif -//!TOKSTYLE+ - // Disable MSG_NOSIGNAL on systems not supporting it, e.g. Windows, FreeBSD #if !defined(MSG_NOSIGNAL) #define MSG_NOSIGNAL 0 @@ -127,12 +121,10 @@ static bool should_ignore_recv_error(int err) return err == EWOULDBLOCK; } -#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION static bool should_ignore_connect_error(int err) { return err == EWOULDBLOCK || err == EINPROGRESS; } -#endif non_null() static const char *inet_ntop4(const struct in_addr *addr, char *buf, size_t bufsize) @@ -488,54 +480,34 @@ struct Network_Addr { non_null() static int sys_close(void *obj, int sock) { -#if defined(FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION) - return 0; -#elif defined(OS_WIN32) +#if defined(OS_WIN32) return closesocket(sock); #else // !OS_WIN32 return close(sock); -#endif // FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION +#endif } non_null() static int sys_accept(void *obj, int sock) { -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - return 2; -#else return accept(sock, nullptr, nullptr); -#endif } non_null() static int sys_bind(void *obj, int sock, const Network_Addr *addr) { -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - return 0; -#else return bind(sock, (const struct sockaddr *)&addr->addr, addr->size); -#endif } non_null() static int sys_listen(void *obj, int sock, int backlog) { -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - return 0; -#else return listen(sock, backlog); -#endif } non_null() static int sys_recvbuf(void *obj, int sock) { -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - // TODO(iphydf): Return something sensible here (from the fuzzer): number of - // bytes to be read from the socket. - return 0; -#else - #ifdef OS_WIN32 u_long count = 0; ioctlsocket(sock, FIONREAD, &count); @@ -545,100 +517,63 @@ static int sys_recvbuf(void *obj, int sock) #endif return count; -#endif } non_null() static int sys_recv(void *obj, int sock, uint8_t *buf, size_t len) { -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - return fuzz_recv(sock, (char *)buf, len, MSG_NOSIGNAL); -#else return recv(sock, (char *)buf, len, MSG_NOSIGNAL); -#endif } non_null() static int sys_send(void *obj, int sock, const uint8_t *buf, size_t len) { -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - return fuzz_send(sock, (const char *)buf, len, MSG_NOSIGNAL); -#else return send(sock, (const char *)buf, len, MSG_NOSIGNAL); -#endif } non_null() static int sys_sendto(void *obj, int sock, const uint8_t *buf, size_t len, const Network_Addr *addr) { -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - return fuzz_sendto(sock, (const char *)buf, len, 0, (const struct sockaddr *)&addr->addr, addr->size); -#else return sendto(sock, (const char *)buf, len, 0, (const struct sockaddr *)&addr->addr, addr->size); -#endif } non_null() static int sys_recvfrom(void *obj, int sock, uint8_t *buf, size_t len, Network_Addr *addr) { -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - socklen_t size = addr->size; - const int ret = fuzz_recvfrom(sock, (char *)buf, len, 0, (struct sockaddr *)&addr->addr, &size); - addr->size = size; - return ret; -#else socklen_t size = addr->size; const int ret = recvfrom(sock, (char *)buf, len, 0, (struct sockaddr *)&addr->addr, &size); addr->size = size; return ret; -#endif } non_null() static int sys_socket(void *obj, int domain, int type, int proto) { -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - return 1; -#else return (int)socket(domain, type, proto); -#endif } non_null() static int sys_socket_nonblock(void *obj, int sock, bool nonblock) { -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - return 0; -#else #ifdef OS_WIN32 u_long mode = nonblock ? 1 : 0; return ioctlsocket(sock, FIONBIO, &mode); #else return fcntl(sock, F_SETFL, O_NONBLOCK, nonblock ? 1 : 0); #endif /* OS_WIN32 */ -#endif /* FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION */ } non_null() static int sys_getsockopt(void *obj, int sock, int level, int optname, void *optval, size_t *optlen) { -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - memset(optval, 0, *optlen); - return 0; -#else socklen_t len = *optlen; const int ret = getsockopt(sock, level, optname, optval, &len); *optlen = len; return ret; -#endif } non_null() static int sys_setsockopt(void *obj, int sock, int level, int optname, const void *optval, size_t optlen) { -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - return 0; -#else return setsockopt(sock, level, optname, optval, optlen); -#endif } static const Network_Funcs system_network_funcs = { @@ -660,6 +595,11 @@ static const Network system_network_obj = {&system_network_funcs}; const Network *system_network(void) { +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + if ((true)) { + return nullptr; + } +#endif #ifdef OS_WIN32 WSADATA wsaData; @@ -1528,11 +1468,9 @@ bool addr_parse_ip(const char *address, IP *to) return false; } -#ifndef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION /** addr_resolve return values */ #define TOX_ADDR_RESOLVE_INET 1 #define TOX_ADDR_RESOLVE_INET6 2 -#endif /** * Uses getaddrinfo to resolve an address into an IP address. @@ -1555,8 +1493,10 @@ non_null(1, 2, 3) nullable(4) static int addr_resolve(const Network *ns, const char *address, IP *to, IP *extra) { #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - return 0; -#else + if ((true)) { + return 0; + } +#endif if (address == nullptr || to == nullptr) { return 0; @@ -1641,7 +1581,6 @@ static int addr_resolve(const Network *ns, const char *address, IP *to, IP *extr freeaddrinfo(server); return result; -#endif } bool addr_resolve_or_parse_ip(const Network *ns, const char *address, IP *to, IP *extra) @@ -1682,8 +1621,11 @@ bool net_connect(const Logger *log, Socket sock, const IP_Port *ip_port) } #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - return addrsize != 0; -#else + if ((true)) { + return true; + } +#endif + Ip_Ntoa ip_str; LOGGER_DEBUG(log, "connecting socket %d to %s:%d", (int)sock.sock, net_ip_ntoa(&ip_port->ip, &ip_str), net_ntohs(ip_port->port)); @@ -1703,20 +1645,22 @@ bool net_connect(const Logger *log, Socket sock, const IP_Port *ip_port) } return true; -#endif } int32_t net_getipport(const char *node, IP_Port **res, int tox_type) { #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - *res = (IP_Port *)calloc(1, sizeof(IP_Port)); - assert(*res != nullptr); - IP_Port *ip_port = *res; - ip_port->ip.ip.v4.uint32 = 0x7F000003; // 127.0.0.3 - ip_port->ip.family = *make_tox_family(AF_INET); + if ((true)) { + *res = (IP_Port *)calloc(1, sizeof(IP_Port)); + assert(*res != nullptr); + IP_Port *ip_port = *res; + ip_port->ip.ip.v4.uint32 = 0x7F000003; // 127.0.0.3 + ip_port->ip.family = *make_tox_family(AF_INET); + + return 1; + } +#endif - return 1; -#else // Try parsing as IP address first. IP_Port parsed = {{{0}}}; @@ -1805,7 +1749,6 @@ int32_t net_getipport(const char *node, IP_Port **res, int tox_type) freeaddrinfo(infos); return count; -#endif } void net_freeipport(IP_Port *ip_ports)