fuzz: Use `__AFL_SHM_ID` for naming test directories
What changed, and why it matters
This change only affects how Bitcoin Core's internal fuzz tests create temporary working folders. When running under the AFL++ fuzzer, it now reuses a folder named after the fuzzer's shared-memory ID and deletes any leftover contents first, instead of creating a new random folder every time. This prevents old test folders from piling up and filling the disk during long fuzzing runs. It is a test-infrastructure cleanup, not a fix for a vulnerability in Bitcoin's network or wallet code.
No security response required. Treat as a normal test-hardening commit. If fuzzing Bitcoin Core, update to avoid disk-space issues during long campaigns.
Security signals we found
Resource exhaustion (disk space) in fuzzing infrastructure
Test-only code path, not reachable in production node operation
No input validation or cryptographic changes
No privilege boundary crossed
Evidence from the diff
The patch modifies BasicTestingSetup in src/test/util/setup_common.cpp. Previously, every test setup generated a random 10-byte hex suffix for the temporary datadir. Under AFL++, this caused each crashed or timed-out fuzz iteration to leave behind a unique datadir, eventually exhausting disk space. The patch checks the __AFL_SHM_ID environment variable; if present, it uses that ID as the directory name and calls fs::remove_all on it before use, so each AFL++ worker reuses and cleans one deterministic path. The non-AFL++ path remains unchanged.
Changed components
src/test/util/setup_common.cppAFL++ fuzzing test harness temporary directory creationInspect captured patch +11 / −2
diff --git a/src/test/util/setup_common.cpp b/src/test/util/setup_common.cpp
index 4e886639..bbc1c9e3 100644
--- a/src/test/util/setup_common.cpp
+++ b/src/test/util/setup_common.cpp
@@ -161,8 +161,17 @@ BasicTestingSetup::BasicTestingSetup(const ChainType chainType, TestOpts opts)
// tests, such as the fuzz tests to run in several processes at the
// same time, add a random element to the path. Keep it small enough to
// avoid a MAX_PATH violation on Windows.
- const auto rand{HexStr(g_rng_temp_path.randbytes(10))};
- m_path_root = fs::temp_directory_path() / TEST_DIR_PATH_ELEMENT / test_name / rand;
+ //
+ // When fuzzing with AFL++, use the shared memory ID for a deterministic
+ // path. This allows for cleanup of leftover directories from timed-out
+ // or crashed iterations, preventing accumulation of stale datadirs.
+ if (const char* shm_id = std::getenv("__AFL_SHM_ID"); shm_id && *shm_id) {
+ m_path_root = fs::temp_directory_path() / TEST_DIR_PATH_ELEMENT / test_name / shm_id;
+ fs::remove_all(m_path_root);
+ } else {
+ const auto rand{HexStr(g_rng_temp_path.randbytes(10))};
+ m_path_root = fs::temp_directory_path() / TEST_DIR_PATH_ELEMENT / test_name / rand;
+ }
TryCreateDirectories(m_path_root);
} else {
// Custom data directory
Why this scored 19/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.