Skip to content

Commit

Permalink
Fix crash inside OverladImpl loops
Browse files Browse the repository at this point in the history
  • Loading branch information
Bronek committed Jul 24, 2024
1 parent ad14d09 commit f273f4d
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 4 deletions.
8 changes: 4 additions & 4 deletions src/xrpld/overlay/detail/OverlayImpl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1157,13 +1157,13 @@ OverlayImpl::getActivePeers(
std::size_t& enabledInSkip) const
{
Overlay::PeerSequence ret;
std::lock_guard lock(mutex_);
std::unique_lock lock(mutex_);

active = ids_.size();
disabled = enabledInSkip = 0;
ret.reserve(ids_.size());

for (auto& [id, w] : ids_)
for (auto& [id, w] : copyIds(lock))
{
if (auto p = w.lock())
{
Expand Down Expand Up @@ -1204,8 +1204,8 @@ OverlayImpl::findPeerByShortID(Peer::id_t const& id) const
std::shared_ptr<Peer>
OverlayImpl::findPeerByPublicKey(PublicKey const& pubKey)
{
std::lock_guard lock(mutex_);
for (auto const& e : ids_)
std::unique_lock lock(mutex_);
for (auto const& e : copyIds(lock))
{
if (auto peer = e.second.lock())
{
Expand Down
17 changes: 17 additions & 0 deletions src/xrpld/overlay/detail/OverlayImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -627,6 +627,23 @@ class OverlayImpl : public Overlay, public reduce_relay::SquelchHandler
}
m_stats.peerDisconnects = getPeerDisconnect();
}

// Use this function to replace ids_ in a buggy loop similar to this:
//
// std::unique_lock lock(mutex_);
// for (auto p : ids_)
// {
// if (auto p = w.lock())
// {
// // . . .
// } // PeerImp owned by p may be destroyed, invalidating the iterator
// }
auto
copyIds(std::unique_lock<std::recursive_mutex>&) const
{
return std::vector<decltype(ids_)::value_type>(
ids_.begin(), ids_.end());
}
};

} // namespace ripple
Expand Down

0 comments on commit f273f4d

Please sign in to comment.