mirror of
https://github.com/XRPLF/rippled.git
synced 2026-10-01 17:28:13 +00:00
fix: Refuse to walk an invalid SHAMap in getMissingNodes
A walk that reaches a position only a leaf may occupy now marks the map Invalid and abandons the descent instead of continuing: SHAMapNodeID::getChildNodeID() throws past kLeafDepth, uncaught, all the way to std::terminate(). It's reachable without going through addKnownNode() at all - InboundLedgers::gotStaleData() stores any parseable node from an unsolicited liAS_NODE reply into the fetch pack by its own hash with no relatedness check - making this a conditioned remote denial of service, not just a single bad packet. As in addKnownNode(), the depth check runs before the full-below cache lookup, for the same cache-doesn't-cover-depth reason. Callers must re-check isValid() before reading an empty result as nothing left to fetch, which getMissingNodes()'s docstring now says.
This commit is contained in:
@@ -143,10 +143,10 @@ private:
|
||||
/**
|
||||
* The map's state.
|
||||
*
|
||||
* A getMissingNodes() walk writes it, through clearSynching(), while whatever
|
||||
* drives the acquisition reads it. Nothing here requires the caller to hold a
|
||||
* lock across the walk, and the acquisition code does not, so this is atomic
|
||||
* rather than guarded.
|
||||
* A getMissingNodes() walk writes it, through setInvalid() and
|
||||
* clearSynching(), while whatever drives the acquisition reads it.
|
||||
* Nothing here requires the caller to hold a lock across the walk, and
|
||||
* the acquisition code does not, so this is atomic rather than guarded.
|
||||
*/
|
||||
std::atomic<SHAMapState> state_;
|
||||
SHAMapType const type_;
|
||||
@@ -339,9 +339,14 @@ public:
|
||||
* concurrency, to discover nodes referenced in the
|
||||
* SHAMap but not available locally.
|
||||
*
|
||||
* Marks the map Invalid and abandons the traversal on meeting an inner
|
||||
* node at or beyond kLeafDepth, a shape no valid tree can have, so
|
||||
* callers must re-check isValid() before reading an empty result as
|
||||
* "nothing left to fetch".
|
||||
*
|
||||
* @param maxNodes The maximum number of found nodes to return
|
||||
* @param filter The filter to use when retrieving nodes
|
||||
* @param return The nodes known to be missing
|
||||
* @return The nodes known to be missing, or empty if the map is Invalid
|
||||
*/
|
||||
std::vector<std::pair<SHAMapNodeID, uint256>>
|
||||
getMissingNodes(int maxNodes, SHAMapSyncFilter const* filter);
|
||||
|
||||
Reference in New Issue
Block a user