What changed, and why it matters
This commit mostly turns on extra compiler warnings and fixes the code that those warnings flagged. The one behavior change is in wallet signature verification: both 'SigV1' and 'SigV2' signatures are now parsed using the same 5-character header length. That is a minor logic simplification, not a clear security fix. The rest of the changes are cleanup to prevent compiler warnings about missing 'fallthrough' annotations and hidden base-class methods.
Treat as routine hardening and code-quality maintenance. No urgent security patch is evident. Review the FORTIFY_SOURCE=2 change for compatibility with supported compilers and consider whether the wallet signature change was intentional, though it appears behavior-preserving.
Security signals we found
Compiler hardening: FORTIFY_SOURCE raised to 2 in Release builds
Compiler hardening: format-security and bidi-chars warnings enabled
Code quality: explicit [[fallthrough]] annotations added
Code quality: -Werror=format-security added
Behavior note: wallet signature verification header length unified for SigV1/SigV2
Evidence from the diff
CMakeLists.txt adds GCC/Clang warnings (-Wimplicit-fallthrough, -Wredundant-decls, -Wduplicated-branches, -Wduplicated-cond, -Woverloaded-virtual, -Wbidi-chars=any) and strengthens FORTIFY_SOURCE from 1 to 2 in Release builds. Source files replace C-style / fallthrough / comments with [[fallthrough]] attributes and add using-declarations to expose base-class add_block overloads in test DBs. wallet2.cpp changes signature header parsing so v1 and v2 share the same header_len (strlen(‘SigV1’)), which is functionally equivalent because both prefixes are 5 characters. No vulnerability is directly fixed by the diff itself.
Changed components
CMake build configurationcontrib/epee/src/net_ssl.cppsrc/cryptonote_protocol/levin_notify.cppsrc/p2p/net_node.cppsrc/wallet/wallet2.cppsrc/blockchain_db/testdb.htests/block_weight/block_weight.cpptests/core_tests/chaingen.cpptests/unit_tests/hardfork.cpptests/unit_tests/long_term_block_weight.cppInspect captured patch +41 / −13
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 1757973..05cbea8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -757,6 +757,18 @@ include(CheckTrezor)
set(C_WARNINGS "-Waggregate-return -Wnested-externs -Wold-style-definition -Wstrict-prototypes")
set(CXX_WARNINGS "-Wno-reorder -Wno-missing-field-initializers")
+ add_c_flag_if_supported(-Wimplicit-fallthrough C_WARNINGS)
+ add_cxx_flag_if_supported(-Wimplicit-fallthrough-per-function CXX_WARNINGS)
+ add_c_flag_if_supported(-Wredundant-decls C_WARNINGS)
+ add_cxx_flag_if_supported(-Wredundant-decls CXX_WARNINGS)
+
+ add_c_flag_if_supported(-Wduplicated-branches C_WARNINGS)
+ add_cxx_flag_if_supported(-Wduplicated-branches CXX_WARNINGS)
+ add_c_flag_if_supported(-Wduplicated-cond C_WARNINGS)
+ add_cxx_flag_if_supported(-Wduplicated-cond CXX_WARNINGS)
+
+ add_cxx_flag_if_supported(-Woverloaded-virtual CXX_WARNINGS)
+
monero_enable_coverage()
# With GCC 6.1.1 the compiled binary malfunctions due to aliasing. Until that
# is fixed in the code (Issue #847), force compiler to be conservative.
@@ -765,15 +777,18 @@ include(CheckTrezor)
# if those don't work for your compiler, single it out where appropriate
if(CMAKE_BUILD_TYPE STREQUAL "Release" AND NOT OPENBSD)
- set(C_SECURITY_FLAGS "${C_SECURITY_FLAGS} -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1")
- set(CXX_SECURITY_FLAGS "${CXX_SECURITY_FLAGS} -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=1")
+ set(C_SECURITY_FLAGS "${C_SECURITY_FLAGS} -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2")
+ set(CXX_SECURITY_FLAGS "${CXX_SECURITY_FLAGS} -U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=2")
endif()
# warnings
add_c_flag_if_supported(-Wformat C_SECURITY_FLAGS)
add_cxx_flag_if_supported(-Wformat CXX_SECURITY_FLAGS)
- add_c_flag_if_supported(-Wformat-security C_SECURITY_FLAGS)
- add_cxx_flag_if_supported(-Wformat-security CXX_SECURITY_FLAGS)
+ add_c_flag_if_supported("-Wformat -Wformat-security" C_SECURITY_FLAGS)
+ add_cxx_flag_if_supported("-Wformat -Wformat-security" CXX_SECURITY_FLAGS)
+
+ add_c_flag_if_supported(-Wbidi-chars=any C_SECURITY_FLAGS)
+ add_cxx_flag_if_supported(-Wbidi-chars=any CXX_SECURITY_FLAGS)
# -fstack-protector
if (NOT OPENBSD AND NOT (WIN32 AND (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND CMAKE_C_COMPILER_VERSION VERSION_LESS 9.1)))
@@ -835,6 +850,8 @@ include(CheckTrezor)
add_cxx_flag_if_supported(-Werror=switch CXX_SECURITY_FLAGS)
add_c_flag_if_supported( -Werror=return-type C_SECURITY_FLAGS)
add_cxx_flag_if_supported(-Werror=return-type CXX_SECURITY_FLAGS)
+ add_c_flag_if_supported( "-Wformat -Werror=format-security" C_SECURITY_FLAGS)
+ add_cxx_flag_if_supported("-Wformat -Werror=format-security" CXX_SECURITY_FLAGS)
# A missing WinAPI prototype (e.g. TryAcquireSRWLock*) must fail the build
if(MINGW)
diff --git a/contrib/epee/src/net_ssl.cpp b/contrib/epee/src/net_ssl.cpp
index 776df5d..c185c8a 100644
--- a/contrib/epee/src/net_ssl.cpp
+++ b/contrib/epee/src/net_ssl.cpp
@@ -248,7 +248,7 @@ boost::asio::ssl::context ssl_options_t::create_context() const
break;
case ssl_verification_t::user_certificates:
ssl_context.set_verify_depth(0);
- /* fallthrough */
+ [[fallthrough]];
case ssl_verification_t::user_ca:
if (!ca_path.empty())
{
diff --git a/src/blockchain_db/testdb.h b/src/blockchain_db/testdb.h
index 6b110ad..1c383d4 100644
--- a/src/blockchain_db/testdb.h
+++ b/src/blockchain_db/testdb.h
@@ -140,6 +140,13 @@ public:
virtual cryptonote::blobdata get_txpool_tx_blob(const crypto::hash& txid, relay_category tx_category) const override { return ""; }
virtual bool for_all_txpool_txes(std::function<bool(const crypto::hash&, const cryptonote::txpool_tx_meta_t&, const cryptonote::blobdata_ref*)>, bool include_blob = false, relay_category category = relay_category::broadcasted) const override { return false; }
+ virtual uint64_t add_block( const std::pair<cryptonote::block, cryptonote::blobdata>& blk
+ , size_t block_weight
+ , uint64_t long_term_block_weight
+ , const cryptonote::difficulty_type& cumulative_difficulty
+ , const uint64_t& coins_generated
+ , const std::vector<std::pair<cryptonote::transaction, cryptonote::blobdata>>& txs
+ ) override { return cryptonote::BlockchainDB::add_block(blk, block_weight, long_term_block_weight, cumulative_difficulty, coins_generated, txs); }
virtual void add_block( const cryptonote::block& blk
, size_t block_weight
, uint64_t long_term_block_weight
diff --git a/src/cryptonote_protocol/levin_notify.cpp b/src/cryptonote_protocol/levin_notify.cpp
index 583c3da..387bcd1 100644
--- a/src/cryptonote_protocol/levin_notify.cpp
+++ b/src/cryptonote_protocol/levin_notify.cpp
@@ -732,7 +732,8 @@ namespace levin
const auto now = std::chrono::steady_clock::now();
const auto min_epoch = noise_enabled ? noise_min_epoch : dandelionpp_min_epoch;
const auto epoch_range = noise_enabled ? noise_epoch_range : dandelionpp_epoch_range;
- const std::size_t out_count = noise_enabled ? CRYPTONOTE_NOISE_CHANNELS : CRYPTONOTE_DANDELIONPP_STEMS;
+ static_assert(CRYPTONOTE_NOISE_CHANNELS == CRYPTONOTE_DANDELIONPP_STEMS, "expected noise and dandelion++ channel counts to match");
+ const std::size_t out_count = CRYPTONOTE_NOISE_CHANNELS;
start_epoch{zone_, min_epoch, epoch_range, out_count, core_}();
@@ -890,7 +891,7 @@ namespace levin
);
break;
}
- /* fallthrough */
+ [[fallthrough]];
case relay_method::fluff:
/* If sending stem/forward/local txes over non public networks,
continue to claim that relay mode even though it used the "fluff"
diff --git a/src/p2p/net_node.cpp b/src/p2p/net_node.cpp
index c0960ea..95c461d 100644
--- a/src/p2p/net_node.cpp
+++ b/src/p2p/net_node.cpp
@@ -89,7 +89,7 @@ namespace
set = client->set_connect_command(remote.as<epee::net_utils::ipv6_network_address>(), std::addressof(proxy.userinfo));
break;
}
- /* fallthrough */
+ [[fallthrough]];
default:
MERROR("Unsupported network address in socks_connect. Try socks5://");
return false;
diff --git a/src/wallet/wallet2.cpp b/src/wallet/wallet2.cpp
index 91a5420..7f2e31b 100644
--- a/src/wallet/wallet2.cpp
+++ b/src/wallet/wallet2.cpp
@@ -12965,10 +12965,9 @@ std::string wallet2::sign(const std::string &data, message_signature_type_t sign
tools::wallet2::message_signature_result_t wallet2::verify(const std::string &data, const cryptonote::account_public_address &address, const std::string &signature) const
{
- static const size_t v1_header_len = strlen("SigV1");
- static const size_t v2_header_len = strlen("SigV2");
- const bool v1 = signature.size() >= v1_header_len && signature.substr(0, v1_header_len) == "SigV1";
- const bool v2 = signature.size() >= v2_header_len && signature.substr(0, v2_header_len) == "SigV2";
+ static const size_t header_len = strlen("SigV1");
+ const bool v1 = signature.size() >= header_len && signature.substr(0, header_len) == "SigV1";
+ const bool v2 = signature.size() >= header_len && signature.substr(0, header_len) == "SigV2";
if (!v1 && !v2)
{
LOG_PRINT_L0("Signature header check error");
@@ -12980,7 +12979,7 @@ tools::wallet2::message_signature_result_t wallet2::verify(const std::string &da
crypto::cn_fast_hash(data.data(), data.size(), hash);
}
std::string decoded;
- if (!tools::base58::decode(signature.substr(v1 ? v1_header_len : v2_header_len), decoded)) {
+ if (!tools::base58::decode(signature.substr(header_len), decoded)) {
LOG_PRINT_L0("Signature decoding error");
return {};
}
diff --git a/tests/block_weight/block_weight.cpp b/tests/block_weight/block_weight.cpp
index b526901..07de0a3 100644
--- a/tests/block_weight/block_weight.cpp
+++ b/tests/block_weight/block_weight.cpp
@@ -57,6 +57,7 @@ private:
public:
TestDB() { m_open = true; }
+ using cryptonote::BaseTestDB::add_block;
virtual void add_block( const cryptonote::block& blk
, size_t block_weight
, uint64_t long_term_block_weight
diff --git a/tests/core_tests/chaingen.cpp b/tests/core_tests/chaingen.cpp
index 71e9758..c300630 100644
--- a/tests/core_tests/chaingen.cpp
+++ b/tests/core_tests/chaingen.cpp
@@ -81,6 +81,7 @@ namespace
public:
TestDB() { m_open = true; }
+ using cryptonote::BaseTestDB::add_block;
virtual void add_block( const cryptonote::block& blk
, size_t block_weight
, uint64_t long_term_block_weight
diff --git a/tests/unit_tests/hardfork.cpp b/tests/unit_tests/hardfork.cpp
index 56958a0..4363be6 100644
--- a/tests/unit_tests/hardfork.cpp
+++ b/tests/unit_tests/hardfork.cpp
@@ -47,6 +47,7 @@ namespace
class TestDB: public cryptonote::BaseTestDB {
public:
virtual uint64_t height() const override { return blocks.size(); }
+ using cryptonote::BaseTestDB::add_block;
virtual void add_block( const block& blk
, size_t block_weight
, uint64_t long_term_block_weight
diff --git a/tests/unit_tests/long_term_block_weight.cpp b/tests/unit_tests/long_term_block_weight.cpp
index ad6ef57..996752e 100644
--- a/tests/unit_tests/long_term_block_weight.cpp
+++ b/tests/unit_tests/long_term_block_weight.cpp
@@ -51,6 +51,7 @@ private:
public:
TestDB() { m_open = true; }
+ using cryptonote::BaseTestDB::add_block;
virtual void add_block( const cryptonote::block& blk
, size_t block_weight
, uint64_t long_term_block_weight
Why this scored 20/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.