Skip to content

Commit 78fa88c

Browse files
committed
Merge bitcoin/bitcoin#31548: fuzz: Abort when global PRNG is used before SeedRand::ZEROS
fa3c787 fuzz: Abort when global PRNG is used before SeedRand::ZEROS (MarcoFalke) Pull request description: This adds one more check to abort when global PRNG is used before SeedRand::ZEROS in fuzz tests. This is achieved by carving out the two remaining uses. First, `g_rng_temp_path_init`, and second the random fallback for `RANDOM_CTX_SEED`, which isn't used in fuzz tests anyway. Requested in bitcoin/bitcoin#31521 (comment) Can be tested by reverting fadd568 and observing an abort when running the `utxo_total_supply` fuzz target. ACKs for top commit: marcofleon: ACK fa3c787 hodlinator: re-ACK fa3c787 ryanofsky: Code review ACK fa3c787. This adds a new check to make that sure that RNG is never seeded during fuzzing after the RNG has been used. Together with existing checks which ensure RNG can only be seeded with zeroes during fuzzing, and that RNG must was seeded at some point if used after fuzzing, this implies it must have been seeded by zeros before being used. Tree-SHA512: 2614928d31c310309bd9021b3e5637b35f64196020fbf9409e978628799691d0efd3f4cf606be9a2db0ef60b010f890c2e70c910eaa2934a7fbf64cd1598fe22
2 parents 5d6f6fd + fa3c787 commit 78fa88c

File tree

3 files changed

+10
-6
lines changed

3 files changed

+10
-6
lines changed

src/test/fuzz/fuzz.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ void FuzzFrameworkRegisterTarget(std::string_view name, TypeTestOneInput target,
7979
static std::string_view g_fuzz_target;
8080
static const TypeTestOneInput* g_test_one_input{nullptr};
8181

82-
inline void test_one_input(FuzzBufferType buffer)
82+
static void test_one_input(FuzzBufferType buffer)
8383
{
8484
CheckGlobals check{};
8585
(*Assert(g_test_one_input))(buffer);
@@ -108,12 +108,12 @@ void ResetCoverageCounters() {}
108108
#endif
109109

110110

111-
void initialize()
111+
static void initialize()
112112
{
113113
// By default, make the RNG deterministic with a fixed seed. This will affect all
114114
// randomness during the fuzz test, except:
115115
// - GetStrongRandBytes(), which is used for the creation of private key material.
116-
// - Creating a BasicTestingSetup or derived class will switch to a random seed.
116+
// - Randomness obtained before this call in g_rng_temp_path_init
117117
SeedRandomStateForTest(SeedRand::ZEROS);
118118

119119
// Set time to the genesis block timestamp for deterministic initialization.

src/test/util/random.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// Copyright (c) 2023 The Bitcoin Core developers
1+
// Copyright (c) 2023-present The Bitcoin Core developers
22
// Distributed under the MIT software license, see the accompanying
33
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
44

@@ -24,7 +24,8 @@ void SeedRandomStateForTest(SeedRand seedtype)
2424
// MakeRandDeterministicDANGEROUS is called, the output of GetRandHash is
2525
// no longer truly random. It should be enough to get the seed once for the
2626
// process.
27-
static const uint256 ctx_seed = []() {
27+
static const auto g_ctx_seed = []() -> std::optional<uint256> {
28+
if constexpr (G_FUZZING) return {};
2829
// If RANDOM_CTX_SEED is set, use that as seed.
2930
if (const char* num{std::getenv(RANDOM_CTX_SEED)}) {
3031
if (auto num_parsed{uint256::FromUserHex(num)}) {
@@ -41,8 +42,9 @@ void SeedRandomStateForTest(SeedRand seedtype)
4142
g_seeded_g_prng_zero = seedtype == SeedRand::ZEROS;
4243
if constexpr (G_FUZZING) {
4344
Assert(g_seeded_g_prng_zero); // Only SeedRandomStateForTest(SeedRand::ZEROS) is allowed in fuzz tests
45+
Assert(!g_used_g_prng); // The global PRNG must not have been used before SeedRandomStateForTest(SeedRand::ZEROS)
4446
}
45-
const uint256& seed{seedtype == SeedRand::FIXED_SEED ? ctx_seed : uint256::ZERO};
47+
const uint256& seed{seedtype == SeedRand::FIXED_SEED ? g_ctx_seed.value() : uint256::ZERO};
4648
LogInfo("Setting random seed for current tests to %s=%s\n", RANDOM_CTX_SEED, seed.GetHex());
4749
MakeRandDeterministicDANGEROUS(seed);
4850
}

src/test/util/setup_common.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,9 @@ constexpr inline auto TEST_DIR_PATH_ELEMENT{"test_common bitcoin"}; // Includes
7878
static FastRandomContext g_rng_temp_path;
7979
static const bool g_rng_temp_path_init{[] {
8080
// Must be initialized before any SeedRandomForTest
81+
Assert(!g_used_g_prng);
8182
(void)g_rng_temp_path.rand64();
83+
g_used_g_prng = false;
8284
return true;
8385
}()};
8486

0 commit comments

Comments
 (0)