Skip to content

Commit 67d1fb1

Browse files
authored
Merge pull request #270 from frstrtr/ltc-doge/noderpc-send-mutex-uaf
ltc: fix NodeRPC::Send UAF (thread-race on shared HTTP client) — .157 crash-loop ship-blocker
2 parents d1e2e6e + 332d3c5 commit 67d1fb1

2 files changed

Lines changed: 7 additions & 0 deletions

File tree

src/impl/ltc/coin/rpc.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ void NodeRPC::sync_reconnect()
132132

133133
std::string NodeRPC::Send(const std::string &request)
134134
{
135+
std::lock_guard<std::mutex> _rpc_lock(m_rpc_mutex);
135136
// Retry once after synchronous reconnect on write/read failure
136137
for (int attempt = 0; attempt < 2; ++attempt)
137138
{

src/impl/ltc/coin/rpc.hpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "node_interface.hpp"
66

77
#include <iostream>
8+
#include <mutex>
89

910
#include <core/uint256.hpp>
1011
#include <core/timer.hpp>
@@ -38,6 +39,11 @@ class NodeRPC : public jsonrpccxx::IClientConnector
3839
beast::tcp_stream m_stream;
3940
boost::asio::ip::tcp::resolver m_resolver;
4041
http::request<http::string_body> m_http_request;
42+
// Serializes Send(): m_http_request + m_stream are NOT thread-safe. The asio
43+
// thread_pool worker (clean_tracker->think->score->getblockheader) and the main
44+
// thread both drive Send() on this single shared client; without this lock T0's
45+
// prepare_payload() frees the Content-Length field element mid-write on T8 -> UAF.
46+
std::mutex m_rpc_mutex;
4147

4248
std::unique_ptr<RPCAuthData> m_auth;
4349
jsonrpccxx::JsonRpcClient m_client;

0 commit comments

Comments
 (0)