fuzz: Abort when global PRNG is used before SeedRand::ZEROS

This commit is contained in:
MarcoFalke 2024-12-20 16:15:32 +01:00
parent 433412fd84
commit fa3c787b62
No known key found for this signature in database
3 changed files with 10 additions and 6 deletions

View file

@ -79,7 +79,7 @@ void FuzzFrameworkRegisterTarget(std::string_view name, TypeTestOneInput target,
static std::string_view g_fuzz_target; static std::string_view g_fuzz_target;
static const TypeTestOneInput* g_test_one_input{nullptr}; static const TypeTestOneInput* g_test_one_input{nullptr};
inline void test_one_input(FuzzBufferType buffer) static void test_one_input(FuzzBufferType buffer)
{ {
CheckGlobals check{}; CheckGlobals check{};
(*Assert(g_test_one_input))(buffer); (*Assert(g_test_one_input))(buffer);
@ -108,12 +108,12 @@ void ResetCoverageCounters() {}
#endif #endif
void initialize() static void initialize()
{ {
// By default, make the RNG deterministic with a fixed seed. This will affect all // By default, make the RNG deterministic with a fixed seed. This will affect all
// randomness during the fuzz test, except: // randomness during the fuzz test, except:
// - GetStrongRandBytes(), which is used for the creation of private key material. // - GetStrongRandBytes(), which is used for the creation of private key material.
// - Creating a BasicTestingSetup or derived class will switch to a random seed. // - Randomness obtained before this call in g_rng_temp_path_init
SeedRandomStateForTest(SeedRand::ZEROS); SeedRandomStateForTest(SeedRand::ZEROS);
// Terminate immediately if a fuzzing harness ever tries to create a socket. // Terminate immediately if a fuzzing harness ever tries to create a socket.

View file

@ -1,4 +1,4 @@
// Copyright (c) 2023 The Bitcoin Core developers // Copyright (c) 2023-present The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying // Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php. // file COPYING or http://www.opensource.org/licenses/mit-license.php.
@ -24,7 +24,8 @@ void SeedRandomStateForTest(SeedRand seedtype)
// MakeRandDeterministicDANGEROUS is called, the output of GetRandHash is // MakeRandDeterministicDANGEROUS is called, the output of GetRandHash is
// no longer truly random. It should be enough to get the seed once for the // no longer truly random. It should be enough to get the seed once for the
// process. // process.
static const uint256 ctx_seed = []() { static const auto g_ctx_seed = []() -> std::optional<uint256> {
if constexpr (G_FUZZING) return {};
// If RANDOM_CTX_SEED is set, use that as seed. // If RANDOM_CTX_SEED is set, use that as seed.
if (const char* num{std::getenv(RANDOM_CTX_SEED)}) { if (const char* num{std::getenv(RANDOM_CTX_SEED)}) {
if (auto num_parsed{uint256::FromUserHex(num)}) { if (auto num_parsed{uint256::FromUserHex(num)}) {
@ -41,8 +42,9 @@ void SeedRandomStateForTest(SeedRand seedtype)
g_seeded_g_prng_zero = seedtype == SeedRand::ZEROS; g_seeded_g_prng_zero = seedtype == SeedRand::ZEROS;
if constexpr (G_FUZZING) { if constexpr (G_FUZZING) {
Assert(g_seeded_g_prng_zero); // Only SeedRandomStateForTest(SeedRand::ZEROS) is allowed in fuzz tests Assert(g_seeded_g_prng_zero); // Only SeedRandomStateForTest(SeedRand::ZEROS) is allowed in fuzz tests
Assert(!g_used_g_prng); // The global PRNG must not have been used before SeedRandomStateForTest(SeedRand::ZEROS)
} }
const uint256& seed{seedtype == SeedRand::FIXED_SEED ? ctx_seed : uint256::ZERO}; const uint256& seed{seedtype == SeedRand::FIXED_SEED ? g_ctx_seed.value() : uint256::ZERO};
LogInfo("Setting random seed for current tests to %s=%s\n", RANDOM_CTX_SEED, seed.GetHex()); LogInfo("Setting random seed for current tests to %s=%s\n", RANDOM_CTX_SEED, seed.GetHex());
MakeRandDeterministicDANGEROUS(seed); MakeRandDeterministicDANGEROUS(seed);
} }

View file

@ -79,7 +79,9 @@ constexpr inline auto TEST_DIR_PATH_ELEMENT{"test_common bitcoin"}; // Includes
static FastRandomContext g_rng_temp_path; static FastRandomContext g_rng_temp_path;
static const bool g_rng_temp_path_init{[] { static const bool g_rng_temp_path_init{[] {
// Must be initialized before any SeedRandomForTest // Must be initialized before any SeedRandomForTest
Assert(!g_used_g_prng);
(void)g_rng_temp_path.rand64(); (void)g_rng_temp_path.rand64();
g_used_g_prng = false;
return true; return true;
}()}; }()};