From a96b84cb1b76e65a639e62f0224f534f89858c18 Mon Sep 17 00:00:00 2001 From: marcofleon Date: Fri, 20 Dec 2024 13:11:14 +0000 Subject: [PATCH] fuzz: Abort when calling system time without setting mock time --- src/test/fuzz/util/check_globals.cpp | 16 ++++++++++++++++ src/test/fuzz/util/check_globals.h | 3 +++ src/util/time.cpp | 4 ++++ 3 files changed, 23 insertions(+) diff --git a/src/test/fuzz/util/check_globals.cpp b/src/test/fuzz/util/check_globals.cpp index fbc5a55598bef..f91a965afced8 100644 --- a/src/test/fuzz/util/check_globals.cpp +++ b/src/test/fuzz/util/check_globals.cpp @@ -5,6 +5,7 @@ #include #include +#include #include #include @@ -16,6 +17,8 @@ struct CheckGlobalsImpl { { g_used_g_prng = false; g_seeded_g_prng_zero = false; + g_used_system_time = false; + SetMockTime(0s); } ~CheckGlobalsImpl() { @@ -34,6 +37,19 @@ struct CheckGlobalsImpl { << std::endl; std::abort(); // Abort, because AFL may try to recover from a std::exit } + + if (g_used_system_time) { + std::cerr << "\n\n" + "The current fuzz target accessed system time.\n\n" + + "This is acceptable, but requires the fuzz target to call \n" + "SetMockTime() at the beginning of processing the fuzz input.\n\n" + + "Without setting mock time, time-dependent behavior can lead \n" + "to non-reproducible bugs or inefficient fuzzing.\n\n" + << std::endl; + std::abort(); + } } }; diff --git a/src/test/fuzz/util/check_globals.h b/src/test/fuzz/util/check_globals.h index 79f247535ae85..12d39c2daf551 100644 --- a/src/test/fuzz/util/check_globals.h +++ b/src/test/fuzz/util/check_globals.h @@ -5,10 +5,13 @@ #ifndef BITCOIN_TEST_FUZZ_UTIL_CHECK_GLOBALS_H #define BITCOIN_TEST_FUZZ_UTIL_CHECK_GLOBALS_H +#include #include #include #include +extern std::atomic g_used_system_time; + struct CheckGlobalsImpl; struct CheckGlobals { CheckGlobals(); diff --git a/src/util/time.cpp b/src/util/time.cpp index e20f30a474570..00f0f4739260d 100644 --- a/src/util/time.cpp +++ b/src/util/time.cpp @@ -20,10 +20,14 @@ void UninterruptibleSleep(const std::chrono::microseconds& n) { std::this_thread::sleep_for(n); } static std::atomic g_mock_time{}; //!< For testing +std::atomic g_used_system_time{false}; NodeClock::time_point NodeClock::now() noexcept { const auto mocktime{g_mock_time.load(std::memory_order_relaxed)}; + if (!mocktime.count()) { + g_used_system_time = true; + } const auto ret{ mocktime.count() ? mocktime :