Merge pull request #6727

13eee1d6a rpc: reject wrong sized txid (moneromooo-monero)
92e6b7df2 easylogging++: fix crash with reentrant logging (moneromooo-monero)
6dd95d530 epee: guard against exceptions in RPC handlers (moneromooo-monero)
90016ad74 blockchain: guard against exceptions in add_new_block/children (moneromooo-monero)
This commit is contained in:
Alexander Blair 2020-08-16 12:55:24 -07:00
commit d73b1b6560
No known key found for this signature in database
GPG Key ID: C64552D877C32479
4 changed files with 57 additions and 15 deletions

View File

@ -42,8 +42,17 @@
MINFO("HTTP [" << m_conn_context.m_remote_address.host_str() << "] " << query_info.m_http_method_str << " " << query_info.m_URI); \ MINFO("HTTP [" << m_conn_context.m_remote_address.host_str() << "] " << query_info.m_http_method_str << " " << query_info.m_URI); \
response.m_response_code = 200; \ response.m_response_code = 200; \
response.m_response_comment = "Ok"; \ response.m_response_comment = "Ok"; \
if(!handle_http_request_map(query_info, response, m_conn_context)) \ try \
{response.m_response_code = 404;response.m_response_comment = "Not found";} \ { \
if(!handle_http_request_map(query_info, response, m_conn_context)) \
{response.m_response_code = 404;response.m_response_comment = "Not found";} \
} \
catch (const std::exception &e) \
{ \
MERROR(m_conn_context << "Exception in handle_http_request_map: " << e.what()); \
response.m_response_code = 500; \
response.m_response_comment = "Internal Server Error"; \
} \
return true; \ return true; \
} }
@ -69,9 +78,11 @@
uint64_t ticks1 = epee::misc_utils::get_tick_count(); \ uint64_t ticks1 = epee::misc_utils::get_tick_count(); \
boost::value_initialized<command_type::response> resp;\ boost::value_initialized<command_type::response> resp;\
MINFO(m_conn_context << "calling " << s_pattern); \ MINFO(m_conn_context << "calling " << s_pattern); \
if(!callback_f(static_cast<command_type::request&>(req), static_cast<command_type::response&>(resp), &m_conn_context)) \ bool res = false; \
try { res = callback_f(static_cast<command_type::request&>(req), static_cast<command_type::response&>(resp), &m_conn_context); } \
catch (const std::exception &e) { MERROR(m_conn_context << "Failed to " << #callback_f << "(): " << e.what()); } \
if (!res) \
{ \ { \
MERROR(m_conn_context << "Failed to " << #callback_f << "()"); \
response_info.m_response_code = 500; \ response_info.m_response_code = 500; \
response_info.m_response_comment = "Internal Server Error"; \ response_info.m_response_comment = "Internal Server Error"; \
return true; \ return true; \
@ -97,9 +108,11 @@
uint64_t ticks1 = misc_utils::get_tick_count(); \ uint64_t ticks1 = misc_utils::get_tick_count(); \
boost::value_initialized<command_type::response> resp;\ boost::value_initialized<command_type::response> resp;\
MINFO(m_conn_context << "calling " << s_pattern); \ MINFO(m_conn_context << "calling " << s_pattern); \
if(!callback_f(static_cast<command_type::request&>(req), static_cast<command_type::response&>(resp), &m_conn_context)) \ bool res = false; \
try { res = callback_f(static_cast<command_type::request&>(req), static_cast<command_type::response&>(resp), &m_conn_context); } \
catch (const std::exception &e) { MERROR(m_conn_context << "Failed to " << #callback_f << "()"); } \
if (!res) \
{ \ { \
MERROR(m_conn_context << "Failed to " << #callback_f << "()"); \
response_info.m_response_code = 500; \ response_info.m_response_code = 500; \
response_info.m_response_comment = "Internal Server Error"; \ response_info.m_response_comment = "Internal Server Error"; \
return true; \ return true; \
@ -184,7 +197,10 @@
fail_resp.jsonrpc = "2.0"; \ fail_resp.jsonrpc = "2.0"; \
fail_resp.id = req.id; \ fail_resp.id = req.id; \
MINFO(m_conn_context << "Calling RPC method " << method_name); \ MINFO(m_conn_context << "Calling RPC method " << method_name); \
if(!callback_f(req.params, resp.result, fail_resp.error, &m_conn_context)) \ bool res = false; \
try { res = callback_f(req.params, resp.result, fail_resp.error, &m_conn_context); } \
catch (const std::exception &e) { MERROR(m_conn_context << "Failed to " << #callback_f << "(): " << e.what()); } \
if (!res) \
{ \ { \
epee::serialization::store_t_to_json(static_cast<epee::json_rpc::error_response&>(fail_resp), response_info.m_body); \ epee::serialization::store_t_to_json(static_cast<epee::json_rpc::error_response&>(fail_resp), response_info.m_body); \
return true; \ return true; \
@ -203,7 +219,10 @@
fail_resp.jsonrpc = "2.0"; \ fail_resp.jsonrpc = "2.0"; \
fail_resp.id = req.id; \ fail_resp.id = req.id; \
MINFO(m_conn_context << "calling RPC method " << method_name); \ MINFO(m_conn_context << "calling RPC method " << method_name); \
if(!callback_f(req.params, resp.result, fail_resp.error, response_info, &m_conn_context)) \ bool res = false; \
try { res = callback_f(req.params, resp.result, fail_resp.error, response_info, &m_conn_context); } \
catch (const std::exception &e) { MERROR(m_conn_context << "Failed to " << #callback_f << "(): " << e.what()); } \
if (!res) \
{ \ { \
epee::serialization::store_t_to_json(static_cast<epee::json_rpc::error_response&>(fail_resp), response_info.m_body); \ epee::serialization::store_t_to_json(static_cast<epee::json_rpc::error_response&>(fail_resp), response_info.m_body); \
return true; \ return true; \
@ -217,7 +236,10 @@
{ \ { \
PREPARE_OBJECTS_FROM_JSON(command_type) \ PREPARE_OBJECTS_FROM_JSON(command_type) \
MINFO(m_conn_context << "calling RPC method " << method_name); \ MINFO(m_conn_context << "calling RPC method " << method_name); \
if(!callback_f(req.params, resp.result, &m_conn_context)) \ bool res = false; \
try { res = callback_f(req.params, resp.result, &m_conn_context); } \
catch (const std::exception &e) { MERROR(m_conn_context << "Failed to " << #callback_f << "(): " << e.what()); } \
if (!res) \
{ \ { \
epee::json_rpc::error_response fail_resp = AUTO_VAL_INIT(fail_resp); \ epee::json_rpc::error_response fail_resp = AUTO_VAL_INIT(fail_resp); \
fail_resp.jsonrpc = "2.0"; \ fail_resp.jsonrpc = "2.0"; \

View File

@ -2968,6 +2968,16 @@ void Writer::initializeLogger(Logger *logger, bool needLock) {
} }
void Writer::processDispatch() { void Writer::processDispatch() {
static std::atomic_flag in_dispatch;
if (in_dispatch.test_and_set())
{
if (m_proceed && m_logger != NULL)
{
m_logger->stream().str(ELPP_LITERAL(""));
m_logger->releaseLock();
}
return;
}
#if ELPP_LOGGING_ENABLED #if ELPP_LOGGING_ENABLED
if (ELPP->hasFlag(LoggingFlag::MultiLoggerSupport)) { if (ELPP->hasFlag(LoggingFlag::MultiLoggerSupport)) {
bool firstDispatched = false; bool firstDispatched = false;
@ -3006,6 +3016,7 @@ void Writer::processDispatch() {
m_logger->releaseLock(); m_logger->releaseLock();
} }
#endif // ELPP_LOGGING_ENABLED #endif // ELPP_LOGGING_ENABLED
in_dispatch.clear();
} }
void Writer::triggerDispatch(void) { void Writer::triggerDispatch(void) {

View File

@ -4371,6 +4371,9 @@ bool Blockchain::update_next_cumulative_weight_limit(uint64_t *long_term_effecti
//------------------------------------------------------------------ //------------------------------------------------------------------
bool Blockchain::add_new_block(const block& bl, block_verification_context& bvc) bool Blockchain::add_new_block(const block& bl, block_verification_context& bvc)
{ {
try
{
LOG_PRINT_L3("Blockchain::" << __func__); LOG_PRINT_L3("Blockchain::" << __func__);
crypto::hash id = get_block_hash(bl); crypto::hash id = get_block_hash(bl);
CRITICAL_REGION_LOCAL(m_tx_pool);//to avoid deadlock lets lock tx_pool for whole add/reorganize process CRITICAL_REGION_LOCAL(m_tx_pool);//to avoid deadlock lets lock tx_pool for whole add/reorganize process
@ -4398,6 +4401,14 @@ bool Blockchain::add_new_block(const block& bl, block_verification_context& bvc)
rtxn_guard.stop(); rtxn_guard.stop();
return handle_block_to_main_chain(bl, id, bvc); return handle_block_to_main_chain(bl, id, bvc);
}
catch (const std::exception &e)
{
LOG_ERROR("Exception at [add_new_block], what=" << e.what());
bvc.m_verifivation_failed = true;
return false;
}
} }
//------------------------------------------------------------------ //------------------------------------------------------------------
//TODO: Refactor, consider returning a failure height and letting //TODO: Refactor, consider returning a failure height and letting

View File

@ -2454,14 +2454,13 @@ namespace cryptonote
{ {
for (const auto &str: req.txids) for (const auto &str: req.txids)
{ {
cryptonote::blobdata txid_data; crypto::hash txid;
if(!epee::string_tools::parse_hexstr_to_binbuff(str, txid_data)) if(!epee::string_tools::hex_to_pod(str, txid))
{ {
failed = true; failed = true;
} }
else else
{ {
crypto::hash txid = *reinterpret_cast<const crypto::hash*>(txid_data.data());
txids.push_back(txid); txids.push_back(txid);
} }
} }
@ -2806,15 +2805,14 @@ namespace cryptonote
res.status = ""; res.status = "";
for (const auto &str: req.txids) for (const auto &str: req.txids)
{ {
cryptonote::blobdata txid_data; crypto::hash txid;
if(!epee::string_tools::parse_hexstr_to_binbuff(str, txid_data)) if(!epee::string_tools::hex_to_pod(str, txid))
{ {
if (!res.status.empty()) res.status += ", "; if (!res.status.empty()) res.status += ", ";
res.status += std::string("invalid transaction id: ") + str; res.status += std::string("invalid transaction id: ") + str;
failed = true; failed = true;
continue; continue;
} }
crypto::hash txid = *reinterpret_cast<const crypto::hash*>(txid_data.data());
cryptonote::blobdata txblob; cryptonote::blobdata txblob;
if (m_core.get_pool_transaction(txid, txblob, relay_category::legacy)) if (m_core.get_pool_transaction(txid, txblob, relay_category::legacy))