blockchain: fix lock ordering in check_against_checkpoints
What changed, and why it matters
This commit changes the order in which two internal locks are acquired in a Monero blockchain checkpoint-checking function. Lock ordering bugs are a common source of deadlocks, where two parts of the program wait forever for each other. The patch itself is very small and appears to be a partial fix rather than a complete security overhaul. There is no direct evidence in the commit that this was exploited or that it caused a concrete vulnerability, but inconsistent lock ordering in critical consensus code is a recognized reliability and potential security risk.
Treat as a stability/reliability fix with possible denial-of-service implications. Review the full lock hierarchy in cryptonote_core to ensure all call sites acquire m_tx_pool before m_blockchain_lock. Monitor for follow-up commits that address related lock-order issues. No immediate emergency response is warranted absent evidence of active exploitation.
Security signals we found
Lock-order inversion (potential deadlock) in blockchain consensus code
Change involves m_tx_pool and m_blockchain_lock synchronization primitives
Function performs database batch_start() while holding multiple locks
No explicit security framing or CVE reference in commit message
Evidence from the diff
In Blockchain::check_against_checkpoints(), the code previously acquired only m_blockchain_lock. The patch now acquires m_tx_pool first, then m_blockchain_lock (via CRITICAL_REGION_LOCAL1). This suggests the global lock hierarchy expected m_tx_pool to be taken before m_blockchain_lock, and this function was violating it. Such violations can lead to AB-BA deadlocks between threads that hold these locks in opposite order. The change is in consensus-critical code that interacts with the transaction pool and database batching.
Changed components
src/cryptonote_core/blockchain.cppBlockchain::check_against_checkpoints()m_tx_pool lockm_blockchain_lockInspect captured patch +2 / −1
diff --git a/src/cryptonote_core/blockchain.cpp b/src/cryptonote_core/blockchain.cpp
index 1b8fca3..a2ee866 100644
--- a/src/cryptonote_core/blockchain.cpp
+++ b/src/cryptonote_core/blockchain.cpp
@@ -4549,7 +4549,8 @@ void Blockchain::check_against_checkpoints(const checkpoints& points, bool enfor
const auto& pts = points.get_points();
bool stop_batch;
- CRITICAL_REGION_LOCAL(m_blockchain_lock);
+ CRITICAL_REGION_LOCAL(m_tx_pool);
+ CRITICAL_REGION_LOCAL1(m_blockchain_lock);
stop_batch = m_db->batch_start();
const uint64_t blockchain_height = m_db->height();
for (const auto& pt : pts)
Why this scored 57/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.