diff --git a/testing/fuzzing/BUILD.bazel b/testing/fuzzing/BUILD.bazel index eed1c6e5..d5778e1c 100644 --- a/testing/fuzzing/BUILD.bazel +++ b/testing/fuzzing/BUILD.bazel @@ -16,7 +16,7 @@ cc_library( ) cc_fuzz_test( - name = "bootstrap_fuzzer", + name = "bootstrap_fuzz_test", srcs = ["bootstrap_harness.cc"], copts = ["-UNDEBUG"], corpus = ["//tools/toktok-fuzzer/corpus:bootstrap_fuzzer"], diff --git a/testing/fuzzing/bootstrap_harness.cc b/testing/fuzzing/bootstrap_harness.cc index 70b139a5..dfcf1d17 100644 --- a/testing/fuzzing/bootstrap_harness.cc +++ b/testing/fuzzing/bootstrap_harness.cc @@ -2,6 +2,7 @@ #include #include "../../toxcore/tox.h" +#include "../../toxcore/tox_struct.h" #include "fuzz_adapter.h" extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); @@ -12,12 +13,18 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) Tox_Err_New error_new; Tox *tox = tox_new(nullptr, &error_new); + uint64_t clock = 0; + mono_time_set_current_time_callback( + tox->mono_time, + [](Mono_Time *mono_time, void *user_data) { return *static_cast(user_data); }, + &clock); + assert(tox != nullptr); assert(error_new == TOX_ERR_NEW_OK); uint8_t pub_key[TOX_PUBLIC_KEY_SIZE] = {0}; - bool success = tox_bootstrap(tox, "127.0.0.1", 12345, pub_key, nullptr); + const bool success = tox_bootstrap(tox, "127.0.0.1", 12345, pub_key, nullptr); assert(success); /* @@ -26,8 +33,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) * NOTE: This should be fine tuned after gathering some experience. */ - for (uint32_t i = 0; i < 100; ++i) { + for (uint32_t i = 0; i < 50; ++i) { tox_iterate(tox, nullptr); + // Move the clock forward a decent amount so all the time-based checks + // trigger more quickly. + clock += 200; } tox_kill(tox); diff --git a/testing/fuzzing/fuzz_adapter.c b/testing/fuzzing/fuzz_adapter.c index da7785a9..82fd6453 100644 --- a/testing/fuzzing/fuzz_adapter.c +++ b/testing/fuzzing/fuzz_adapter.c @@ -1,8 +1,6 @@ #include "fuzz_adapter.h" struct fuzz_buf { - /* Monotonic counter for time replacement */ - uint64_t counter; /* Fuzz data buffer */ const uint8_t *cur; const uint8_t *end; @@ -17,7 +15,6 @@ static struct fuzz_buf data; void network_adapter_init(const uint8_t *buf, size_t length) { - data.counter = 0; data.cur = buf; data.end = buf + length; } @@ -90,8 +87,3 @@ void fuzz_random_bytes(uint8_t *rnd, size_t length) memcpy(rnd, data.cur, bytes_read); data.cur += bytes_read; } - -uint64_t fuzz_get_count(void) -{ - return data.counter++; -} diff --git a/testing/fuzzing/fuzz_adapter.h b/testing/fuzzing/fuzz_adapter.h index f2666d25..91fdbc76 100644 --- a/testing/fuzzing/fuzz_adapter.h +++ b/testing/fuzzing/fuzz_adapter.h @@ -37,10 +37,6 @@ 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); -/* The following function replaces all time bases with a monotonic counter */ - -uint64_t fuzz_get_count(void); - #ifdef __cplusplus } #endif diff --git a/toxcore/mono_time.c b/toxcore/mono_time.c index c75c53ac..2a2ec3a2 100644 --- a/toxcore/mono_time.c +++ b/toxcore/mono_time.c @@ -32,12 +32,6 @@ #include "ccompat.h" -//!TOKSTYLE- -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -#include "../testing/fuzzing/fuzz_adapter.h" -#endif -//!TOKSTYLE+ - /** don't call into system billions of times for no reason */ struct Mono_Time { uint64_t cur_time; @@ -110,6 +104,11 @@ static uint64_t current_time_monotonic_default(Mono_Time *mono_time, void *user_ non_null(1) nullable(2) static uint64_t current_time_monotonic_default(Mono_Time *mono_time, void *user_data) { +#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION + // This assert should always fail. If it does, the fuzzing harness didn't + // override the mono time callback. + assert(mono_time == nullptr); +#endif struct timespec clock_mono; clock_gettime(CLOCK_MONOTONIC, &clock_mono); return timespec_to_u64(clock_mono); @@ -118,14 +117,6 @@ static uint64_t current_time_monotonic_default(Mono_Time *mono_time, void *user_ #endif // !OS_WIN32 -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -non_null(1) nullable(2) -static uint64_t current_time_monotonic_dummy(Mono_Time *mono_time, void *user_data) -{ - return fuzz_get_count(); -} -#endif - Mono_Time *mono_time_new(void) { Mono_Time *mono_time = (Mono_Time *)calloc(1, sizeof(Mono_Time)); @@ -147,11 +138,7 @@ Mono_Time *mono_time_new(void) return nullptr; } -#ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - mono_time->current_time_callback = current_time_monotonic_dummy; -#else mono_time->current_time_callback = current_time_monotonic_default; -#endif mono_time->user_data = nullptr; #ifdef OS_WIN32 @@ -169,12 +156,15 @@ Mono_Time *mono_time_new(void) mono_time->cur_time = 0; #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION - mono_time->base_time = 0; // Maximum reproducibility + // Maximum reproducibility and don't update mono_time before the harness has + // had a chance to set the callback. + // TODO(iphydf): Put mono time callback into Tox_Options with accessors only + // in tox_private.h. + mono_time->base_time = 0; #else mono_time->base_time = (uint64_t)time(nullptr) - (current_time_monotonic(mono_time) / 1000ULL); -#endif - mono_time_update(mono_time); +#endif return mono_time; }