What changed, and why it matters
This commit adds exception handling around two network callback functions and changes one block-queue function to log errors instead of throwing exceptions. It appears aimed at preventing unhandled exceptions from crashing or destabilizing network connections during message processing. The change is defensive and does not obviously introduce a security vulnerability, but it is only a partial hardening patch.
Treat as a routine stability/hardening change. Review whether swallowed exceptions could leave connection or block-queue state inconsistent. No immediate security response is indicated from the diff alone.
Security signals we found
Unhandled exceptions in asynchronous network handlers can terminate connections or threads
Exception-swallowing can mask error conditions and complicate debugging
CHECK_AND_ASSERT_THROW_MES changed to non-throwing variant, altering control flow on error
No input validation changes or cryptographic fixes present
Evidence from the diff
The patch introduces a new macro CATCH_ENTRY_SWALLOW_EX that logs exceptions and swallows them. It wraps m_handler.handle_recv and m_handler.handle_qued_callback inside boost::asio::posted lambdas with TRY_ENTRY/CATCH_ENTRY_SWALLOW_EX. It also converts three CHECK_AND_ASSERT_THROW_MES calls in block_queue::reset_next_span_time to CHECK_AND_ASSERT_MES_NO_RET, which logs and returns instead of throwing. The intent is to stop exceptions from propagating out of async handlers and from aborting block-queue operations.
Changed components
contrib/epee/include/misc_log_ex.hcontrib/epee/include/net/abstract_tcp_server2.inlsrc/cryptonote_protocol/block_queue.cppInspect captured patch +20 / −4
diff --git a/contrib/epee/include/misc_log_ex.h b/contrib/epee/include/misc_log_ex.h
index 4b0a09a..fdd7d8c 100644
--- a/contrib/epee/include/misc_log_ex.h
+++ b/contrib/epee/include/misc_log_ex.h
@@ -172,6 +172,17 @@ namespace debug
return return_val; \
}
+#define CATCH_ENTRY_SWALLOW_EX(location) } \
+ catch(const std::exception& ex) \
+{ \
+ (void)(ex); \
+ LOG_ERROR("Exception at [" << location << "], what=" << ex.what()); \
+}\
+ catch(...)\
+{\
+ LOG_ERROR("Exception at [" << location << "], generic exception \"...\"");\
+}
+
#define CATCH_ENTRY_L0(lacation, return_val) CATCH_ENTRY(lacation, return_val)
#define CATCH_ENTRY_L1(lacation, return_val) CATCH_ENTRY(lacation, return_val)
#define CATCH_ENTRY_L2(lacation, return_val) CATCH_ENTRY(lacation, return_val)
diff --git a/contrib/epee/include/net/abstract_tcp_server2.inl b/contrib/epee/include/net/abstract_tcp_server2.inl
index 62c39c7..0772644 100644
--- a/contrib/epee/include/net/abstract_tcp_server2.inl
+++ b/contrib/epee/include/net/abstract_tcp_server2.inl
@@ -425,10 +425,13 @@ namespace net_utils
boost::asio::post(
connection_basic::strand_,
[this, self, bytes_transferred]{
- bool success = m_handler.handle_recv(
+ bool success = false;
+ TRY_ENTRY();
+ success = m_handler.handle_recv(
reinterpret_cast<char *>(m_state.data.read.buffer.data()),
bytes_transferred
);
+ CATCH_ENTRY_SWALLOW_EX("m_handler.handle_recv");
std::lock_guard<std::mutex> guard(m_state.lock);
const bool error_status = m_state.status == status_t::INTERRUPTED
|| m_state.status == status_t::TERMINATING
@@ -1188,7 +1191,9 @@ namespace net_utils
auto self = connection<T>::shared_from_this();
++m_state.protocol.wait_callback;
boost::asio::post(connection_basic::strand_, [this, self]{
+ TRY_ENTRY();
m_handler.handle_qued_callback();
+ CATCH_ENTRY_SWALLOW_EX("m_handler.handle_qued_callback");
std::lock_guard<std::mutex> guard(m_state.lock);
--m_state.protocol.wait_callback;
if (m_state.status == status_t::INTERRUPTED)
diff --git a/src/cryptonote_protocol/block_queue.cpp b/src/cryptonote_protocol/block_queue.cpp
index 5ed9e99..c564991 100644
--- a/src/cryptonote_protocol/block_queue.cpp
+++ b/src/cryptonote_protocol/block_queue.cpp
@@ -345,10 +345,10 @@ std::pair<uint64_t, uint64_t> block_queue::get_next_span_if_scheduled(std::vecto
void block_queue::reset_next_span_time(boost::posix_time::ptime t)
{
boost::unique_lock<boost::recursive_mutex> lock(mutex);
- CHECK_AND_ASSERT_THROW_MES(!blocks.empty(), "No next span to reset time");
+ CHECK_AND_ASSERT_MES_NO_RET(!blocks.empty(), "No next span to reset time");
block_map::iterator i = blocks.begin();
- CHECK_AND_ASSERT_THROW_MES(i != blocks.end(), "No next span to reset time");
- CHECK_AND_ASSERT_THROW_MES(i->blocks.empty(), "Next span is not empty");
+ CHECK_AND_ASSERT_MES_NO_RET(i != blocks.end(), "No next span to reset time");
+ CHECK_AND_ASSERT_MES_NO_RET(i->blocks.empty(), "Next span is not empty");
(boost::posix_time::ptime&)i->time = t; // sod off, time doesn't influence sorting
}
Why this scored 45/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.