nanobench: fix perf counter buffer init
What changed, and why it matters
This is a small bug fix in Bitcoin Core's internal benchmarking header (nanobench). The code intended to create three empty placeholder slots in some performance-counter buffers, but accidentally created a single slot containing the number 3. Under normal use this gets corrected before it matters, but a default-constructed object could read past the single element. It is a correctness/reliability fix in benchmark tooling, not a network-facing security vulnerability.
Treat as a routine code-quality/correctness fix. No urgent security action is required. Reviewers may want to confirm no other brace-initialized vectors in nanobench.h have the same semantic confusion.
Security signals we found
off-by-one / initialization bug in low-level performance counter buffer
potential out-of-bounds read if default-constructed object is used before resize
fix is defensive/correctness rather than reactive to an exploit
no mention of CVE, advisory, researcher credit, or security disclosure
Evidence from the diff
The patch changes brace-initialization std::vector<uint64_t> mCounters{3} to parenthesis construction std::vector<uint64_t> mCounters = std::vector<uint64_t>(3) (and two analogous members). Brace-init with a single integer creates a vector of size 1 whose element is 3, not a vector of size 3. The intended invariant is that the perf-counter read buffer has at least three metadata slots. The commit message notes that normal construction paths usually resize the buffer or set an error flag before indexed reads, so the bug is latent rather than actively triggered in typical runs. The fix makes a default-constructed LinuxPerformanceCounters satisfy the documented invariant.
Changed components
src/bench/nanobench.hLinuxPerformanceCounters classBitcoin Core benchmark harness (non-consensus, non-network)Inspect captured patch +3 / −3
diff --git a/src/bench/nanobench.h b/src/bench/nanobench.h
index 78512908..a66e92a4 100644
--- a/src/bench/nanobench.h
+++ b/src/bench/nanobench.h
@@ -2654,9 +2654,9 @@ private:
std::map<uint64_t, Target> mIdToTarget{};
// start with minimum size of 3 for read_format
- std::vector<uint64_t> mCounters{3};
- std::vector<uint64_t> mCalibratedOverhead{3};
- std::vector<uint64_t> mLoopOverhead{3};
+ std::vector<uint64_t> mCounters = std::vector<uint64_t>(3);
+ std::vector<uint64_t> mCalibratedOverhead = std::vector<uint64_t>(3);
+ std::vector<uint64_t> mLoopOverhead = std::vector<uint64_t>(3);
uint64_t mTimeEnabledNanos = 0;
uint64_t mTimeRunningNanos = 0;
Why this scored 18/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.