coins: replace `std::distance` with unambiguous pointer subtraction
What changed, and why it matters
This change fixes a low-level programming issue in Bitcoin Core's custom memory pool allocator. The old code used a standard library function (`std::distance`) to calculate how many unused bytes remained in a memory chunk. That function can have undefined behavior when given null pointers, which could occur when no chunk had been allocated yet. The new code uses plain pointer subtraction, which is explicitly defined to give zero when both pointers are null. The practical security impact is likely limited because the undefined behavior only arises in a specific no-memory-allocated state and the result is used only to decide whether to add leftover bytes to a freelist.
Treat as a code-quality and undefined-behavior hardening fix. Include in routine backports if the allocator is used in release branches. No emergency response is warranted absent evidence of exploitable memory corruption.
Security signals we found
Undefined behavior fix: `std::distance` on potentially null raw pointers
Memory allocator hardening in custom pool allocator
Pointer arithmetic made explicit and well-defined for equal-null case
No explicit security claim or CVE in commit message
Evidence from the diff
In PoolResource::AllocateChunk() in src/support/allocators/pool.h, the remaining available bytes were computed with std::distance(m_available_memory_it, m_available_memory_end). Both iterators are raw pointers (CharPtr). When AllocateChunk() is called before any chunk has been allocated, both pointers can be nullptr. Calling std::distance on two null pointers is undefined behavior in C++ because the standard requires valid pointers into the same array/object. The patch replaces this with m_available_memory_end - m_available_memory_it, which for pointers is well-defined to yield 0 when both are null (since subtracting two equal pointers, including null, gives zero). The value is then used to decide whether to place a trailing freelist node. This is a defensive fix for undefined behavior rather than a clearly exploitable vulnerability.
Changed components
src/support/allocators/pool.hPoolResource::AllocateChunk()Inspect captured patch +1 / −1
diff --git a/src/support/allocators/pool.h b/src/support/allocators/pool.h
index abca09ad..d4ce68b9 100644
--- a/src/support/allocators/pool.h
+++ b/src/support/allocators/pool.h
@@ -155,7 +155,7 @@ class PoolResource final
void AllocateChunk()
{
// if there is still any available memory left, put it into the freelist.
- size_t remaining_available_bytes = std::distance(m_available_memory_it, m_available_memory_end);
+ size_t remaining_available_bytes = m_available_memory_end - m_available_memory_it;
if (0 != remaining_available_bytes) {
ASAN_UNPOISON_MEMORY_REGION(m_available_memory_it, sizeof(ListNode));
PlacementAddToList(m_available_memory_it, m_free_lists[remaining_available_bytes / ELEM_ALIGN_BYTES]);
Why this scored 42/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.