diff options
-rwxr-xr-x | contrib/devtools/security-check.py | 16 | ||||
-rwxr-xr-x | contrib/devtools/test-security-check.py | 12 | ||||
-rw-r--r-- | depends/packages/boost.mk | 1 | ||||
-rw-r--r-- | doc/build-freebsd.md | 2 | ||||
-rw-r--r-- | doc/build-netbsd.md | 2 | ||||
-rw-r--r-- | doc/build-openbsd.md | 2 | ||||
-rw-r--r-- | doc/build-osx.md | 2 | ||||
-rw-r--r-- | doc/build-unix.md | 2 | ||||
-rw-r--r-- | doc/build-windows.md | 2 | ||||
-rw-r--r-- | src/net.cpp | 2 | ||||
-rw-r--r-- | src/protocol.cpp | 11 | ||||
-rw-r--r-- | src/protocol.h | 8 | ||||
-rw-r--r-- | src/rpc/misc.cpp | 2 | ||||
-rw-r--r-- | src/scheduler.cpp | 3 | ||||
-rw-r--r-- | src/test/fuzz/integer.cpp | 4 | ||||
-rw-r--r-- | src/wallet/db.cpp | 7 | ||||
-rw-r--r-- | src/wallet/rpcwallet.cpp | 3 | ||||
-rw-r--r-- | src/wallet/wallet.cpp | 9 | ||||
-rw-r--r-- | src/wallet/wallet.h | 2 |
19 files changed, 52 insertions, 40 deletions
diff --git a/contrib/devtools/security-check.py b/contrib/devtools/security-check.py index b6628c2ad5..0b59d8eada 100755 --- a/contrib/devtools/security-check.py +++ b/contrib/devtools/security-check.py @@ -188,6 +188,19 @@ def check_NX(executable) -> bool: binary = lief.parse(executable) return binary.has_nx +def check_control_flow(executable) -> bool: + ''' + Check for control flow instrumentation + ''' + binary = lief.parse(executable) + + content = binary.get_content_from_virtual_address(binary.entrypoint, 4, lief.Binary.VA_TYPES.AUTO) + + if content == [243, 15, 30, 250]: # endbr64 + return True + return False + + CHECKS = { 'ELF': [ ('PIE', check_ELF_PIE), @@ -208,7 +221,8 @@ CHECKS = { ('NOUNDEFS', check_MACHO_NOUNDEFS), ('NX', check_NX), ('LAZY_BINDINGS', check_MACHO_LAZY_BINDINGS), - ('Canary', check_MACHO_Canary) + ('Canary', check_MACHO_Canary), + ('CONTROL_FLOW', check_control_flow), ] } diff --git a/contrib/devtools/test-security-check.py b/contrib/devtools/test-security-check.py index 28b5f57489..c079fe5b4d 100755 --- a/contrib/devtools/test-security-check.py +++ b/contrib/devtools/test-security-check.py @@ -77,16 +77,18 @@ class TestSecurityChecks(unittest.TestCase): write_testcode(source) self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-flat_namespace','-Wl,-allow_stack_execute','-fno-stack-protector']), - (1, executable+': failed PIE NOUNDEFS NX LAZY_BINDINGS Canary')) + (1, executable+': failed PIE NOUNDEFS NX LAZY_BINDINGS Canary CONTROL_FLOW')) self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-flat_namespace','-Wl,-allow_stack_execute','-fstack-protector-all']), - (1, executable+': failed PIE NOUNDEFS NX LAZY_BINDINGS')) + (1, executable+': failed PIE NOUNDEFS NX LAZY_BINDINGS CONTROL_FLOW')) self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-flat_namespace','-fstack-protector-all']), - (1, executable+': failed PIE NOUNDEFS LAZY_BINDINGS')) + (1, executable+': failed PIE NOUNDEFS LAZY_BINDINGS CONTROL_FLOW')) self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-fstack-protector-all']), - (1, executable+': failed PIE LAZY_BINDINGS')) + (1, executable+': failed PIE LAZY_BINDINGS CONTROL_FLOW')) self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-bind_at_load','-fstack-protector-all']), + (1, executable+': failed PIE CONTROL_FLOW')) + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-no_pie','-Wl,-bind_at_load','-fstack-protector-all', '-fcf-protection=full']), (1, executable+': failed PIE')) - self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-pie','-Wl,-bind_at_load','-fstack-protector-all']), + self.assertEqual(call_security_check(cc, source, executable, ['-Wl,-pie','-Wl,-bind_at_load','-fstack-protector-all', '-fcf-protection=full']), (0, '')) clean_files(source, executable) diff --git a/depends/packages/boost.mk b/depends/packages/boost.mk index 0800c63dfc..6b3b293140 100644 --- a/depends/packages/boost.mk +++ b/depends/packages/boost.mk @@ -26,6 +26,7 @@ $(package)_config_libraries=filesystem,system,test $(package)_cxxflags=-std=c++17 -fvisibility=hidden $(package)_cxxflags_linux=-fPIC $(package)_cxxflags_android=-fPIC +$(package)_cxxflags_darwin=-fcf-protection=full endef define $(package)_preprocess_cmds diff --git a/doc/build-freebsd.md b/doc/build-freebsd.md index 18ea84c579..da2ab61c2a 100644 --- a/doc/build-freebsd.md +++ b/doc/build-freebsd.md @@ -124,6 +124,6 @@ This explicitly enables the GUI and disables legacy wallet support. If `qt5` is **Important**: Use `gmake` (the non-GNU `make` will exit with an error). ```bash -gmake # use -jX here for parallelism +gmake # use "-j N" for N parallel jobs gmake check # Run tests if Python 3 is available ``` diff --git a/doc/build-netbsd.md b/doc/build-netbsd.md index 47049a780e..edabd71611 100644 --- a/doc/build-netbsd.md +++ b/doc/build-netbsd.md @@ -76,6 +76,6 @@ Without wallet: Build and run the tests: ```bash -gmake # use -jX here for parallelism +gmake # use "-j N" here for N parallel jobs gmake check ``` diff --git a/doc/build-openbsd.md b/doc/build-openbsd.md index dccd7b1335..613aea438f 100644 --- a/doc/build-openbsd.md +++ b/doc/build-openbsd.md @@ -90,7 +90,7 @@ To configure with GUI: Build and run the tests: ```bash -gmake # use -jX here for parallelism +gmake # use "-j N" here for N parallel jobs gmake check ``` diff --git a/doc/build-osx.md b/doc/build-osx.md index 16c6da66d5..ab298f5f2c 100644 --- a/doc/build-osx.md +++ b/doc/build-osx.md @@ -270,7 +270,7 @@ After configuration, you are ready to compile. Run the following in your terminal to compile Bitcoin Core: ``` bash -make -jx # use -jX here for parallelism +make # use "-j N" here for N parallel jobs make check # Run tests if Python 3 is available ``` diff --git a/doc/build-unix.md b/doc/build-unix.md index 0c438db29a..73c0bf8779 100644 --- a/doc/build-unix.md +++ b/doc/build-unix.md @@ -20,7 +20,7 @@ To Build ```bash ./autogen.sh ./configure -make +make # use "-j N" for N parallel jobs make install # optional ``` diff --git a/doc/build-windows.md b/doc/build-windows.md index d1b84eef42..0e92a8aeea 100644 --- a/doc/build-windows.md +++ b/doc/build-windows.md @@ -105,7 +105,7 @@ Build using: cd .. ./autogen.sh CONFIG_SITE=$PWD/depends/x86_64-w64-mingw32/share/config.site ./configure --prefix=/ - make + make # use "-j N" for N parallel jobs sudo bash -c "echo 1 > /proc/sys/fs/binfmt_misc/status" # Enable WSL support for Win32 applications. ## Depends system diff --git a/src/net.cpp b/src/net.cpp index bbc0b81056..05588d7406 100644 --- a/src/net.cpp +++ b/src/net.cpp @@ -2245,7 +2245,7 @@ void CConnman::ThreadI2PAcceptIncoming() } if (!advertising_listen_addr) { - AddLocal(conn.me, LOCAL_BIND); + AddLocal(conn.me, LOCAL_MANUAL); advertising_listen_addr = true; } diff --git a/src/protocol.cpp b/src/protocol.cpp index 2f77ec18e6..2e70b41e4c 100644 --- a/src/protocol.cpp +++ b/src/protocol.cpp @@ -87,25 +87,16 @@ const static std::string allNetMessageTypes[] = { }; const static std::vector<std::string> allNetMessageTypesVec(std::begin(allNetMessageTypes), std::end(allNetMessageTypes)); -CMessageHeader::CMessageHeader() -{ - memset(pchMessageStart, 0, MESSAGE_START_SIZE); - memset(pchCommand, 0, sizeof(pchCommand)); - memset(pchChecksum, 0, CHECKSUM_SIZE); -} - CMessageHeader::CMessageHeader(const MessageStartChars& pchMessageStartIn, const char* pszCommand, unsigned int nMessageSizeIn) { memcpy(pchMessageStart, pchMessageStartIn, MESSAGE_START_SIZE); - // Copy the command name, zero-padding to COMMAND_SIZE bytes + // Copy the command name size_t i = 0; for (; i < COMMAND_SIZE && pszCommand[i] != 0; ++i) pchCommand[i] = pszCommand[i]; assert(pszCommand[i] == 0); // Assert that the command name passed in is not longer than COMMAND_SIZE - for (; i < COMMAND_SIZE; ++i) pchCommand[i] = 0; nMessageSize = nMessageSizeIn; - memset(pchChecksum, 0, CHECKSUM_SIZE); } std::string CMessageHeader::GetCommand() const diff --git a/src/protocol.h b/src/protocol.h index c73484bdf6..aaa9f1df40 100644 --- a/src/protocol.h +++ b/src/protocol.h @@ -38,7 +38,7 @@ public: static constexpr size_t HEADER_SIZE = MESSAGE_START_SIZE + COMMAND_SIZE + MESSAGE_SIZE_SIZE + CHECKSUM_SIZE; typedef unsigned char MessageStartChars[MESSAGE_START_SIZE]; - explicit CMessageHeader(); + explicit CMessageHeader() = default; /** Construct a P2P message header from message-start characters, a command and the size of the message. * @note Passing in a `pszCommand` longer than COMMAND_SIZE will result in a run-time assertion error. @@ -50,10 +50,10 @@ public: SERIALIZE_METHODS(CMessageHeader, obj) { READWRITE(obj.pchMessageStart, obj.pchCommand, obj.nMessageSize, obj.pchChecksum); } - char pchMessageStart[MESSAGE_START_SIZE]; - char pchCommand[COMMAND_SIZE]; + char pchMessageStart[MESSAGE_START_SIZE]{}; + char pchCommand[COMMAND_SIZE]{}; uint32_t nMessageSize{std::numeric_limits<uint32_t>::max()}; - uint8_t pchChecksum[CHECKSUM_SIZE]; + uint8_t pchChecksum[CHECKSUM_SIZE]{}; }; /** diff --git a/src/rpc/misc.cpp b/src/rpc/misc.cpp index 0e0da8f22b..ab239fe79c 100644 --- a/src/rpc/misc.cpp +++ b/src/rpc/misc.cpp @@ -424,7 +424,7 @@ static RPCHelpMan mockscheduler() // check params are valid values RPCTypeCheck(request.params, {UniValue::VNUM}); int64_t delta_seconds = request.params[0].get_int64(); - if ((delta_seconds <= 0) || (delta_seconds > 3600)) { + if (delta_seconds <= 0 || delta_seconds > 3600) { throw std::runtime_error("delta_time must be between 1 and 3600 seconds (1 hr)"); } diff --git a/src/scheduler.cpp b/src/scheduler.cpp index b3ee23f139..02ada969a4 100644 --- a/src/scheduler.cpp +++ b/src/scheduler.cpp @@ -5,6 +5,7 @@ #include <scheduler.h> #include <random.h> +#include <util/time.h> #include <assert.h> #include <functional> @@ -80,7 +81,7 @@ void CScheduler::schedule(CScheduler::Function f, std::chrono::system_clock::tim void CScheduler::MockForward(std::chrono::seconds delta_seconds) { - assert(delta_seconds.count() > 0 && delta_seconds < std::chrono::hours{1}); + assert(delta_seconds > 0s && delta_seconds <= 1h); { LOCK(newTaskMutex); diff --git a/src/test/fuzz/integer.cpp b/src/test/fuzz/integer.cpp index 5bc99ddcb9..e9fa343896 100644 --- a/src/test/fuzz/integer.cpp +++ b/src/test/fuzz/integer.cpp @@ -122,10 +122,6 @@ FUZZ_TARGET_INIT(integer, initialize_integer) assert(dynamic_usage == incremental_dynamic_usage * i64s.size()); } (void)MillisToTimeval(i64); - const double d = ser_uint64_to_double(u64); - assert(ser_double_to_uint64(d) == u64); - const float f = ser_uint32_to_float(u32); - assert(ser_float_to_uint32(f) == u32); (void)SighashToStr(uch); (void)SipHashUint256(u64, u64, u256); (void)SipHashUint256Extra(u64, u64, u256, u32); diff --git a/src/wallet/db.cpp b/src/wallet/db.cpp index cd49baeb78..5bf037b222 100644 --- a/src/wallet/db.cpp +++ b/src/wallet/db.cpp @@ -18,7 +18,12 @@ std::vector<fs::path> ListDatabases(const fs::path& wallet_dir) for (auto it = fs::recursive_directory_iterator(wallet_dir, ec); it != fs::recursive_directory_iterator(); it.increment(ec)) { if (ec) { - LogPrintf("%s: %s %s\n", __func__, ec.message(), it->path().string()); + if (fs::is_directory(*it)) { + it.no_push(); + LogPrintf("%s: %s %s -- skipping.\n", __func__, ec.message(), it->path().string()); + } else { + LogPrintf("%s: %s %s\n", __func__, ec.message(), it->path().string()); + } continue; } diff --git a/src/wallet/rpcwallet.cpp b/src/wallet/rpcwallet.cpp index 326e183a7f..5567d183b6 100644 --- a/src/wallet/rpcwallet.cpp +++ b/src/wallet/rpcwallet.cpp @@ -2970,8 +2970,9 @@ static RPCHelpMan listunspent() cctl.m_avoid_address_reuse = false; cctl.m_min_depth = nMinDepth; cctl.m_max_depth = nMaxDepth; + cctl.m_include_unsafe_inputs = include_unsafe; LOCK(pwallet->cs_wallet); - pwallet->AvailableCoins(vecOutputs, !include_unsafe, &cctl, nMinimumAmount, nMaximumAmount, nMinimumSumAmount, nMaximumCount); + pwallet->AvailableCoins(vecOutputs, &cctl, nMinimumAmount, nMaximumAmount, nMinimumSumAmount, nMaximumCount); } LOCK(pwallet->cs_wallet); diff --git a/src/wallet/wallet.cpp b/src/wallet/wallet.cpp index 60d60d1e81..456c26ea31 100644 --- a/src/wallet/wallet.cpp +++ b/src/wallet/wallet.cpp @@ -2197,7 +2197,7 @@ CAmount CWallet::GetAvailableBalance(const CCoinControl* coinControl) const CAmount balance = 0; std::vector<COutput> vCoins; - AvailableCoins(vCoins, true, coinControl); + AvailableCoins(vCoins, coinControl); for (const COutput& out : vCoins) { if (out.fSpendable) { balance += out.tx->tx->vout[out.i].nValue; @@ -2206,7 +2206,7 @@ CAmount CWallet::GetAvailableBalance(const CCoinControl* coinControl) const return balance; } -void CWallet::AvailableCoins(std::vector<COutput>& vCoins, bool fOnlySafe, const CCoinControl* coinControl, const CAmount& nMinimumAmount, const CAmount& nMaximumAmount, const CAmount& nMinimumSumAmount, const uint64_t nMaximumCount) const +void CWallet::AvailableCoins(std::vector<COutput>& vCoins, const CCoinControl* coinControl, const CAmount& nMinimumAmount, const CAmount& nMaximumAmount, const CAmount& nMinimumSumAmount, const uint64_t nMaximumCount) const { AssertLockHeld(cs_wallet); @@ -2217,6 +2217,7 @@ void CWallet::AvailableCoins(std::vector<COutput>& vCoins, bool fOnlySafe, const bool allow_used_addresses = !IsWalletFlagSet(WALLET_FLAG_AVOID_REUSE) || (coinControl && !coinControl->m_avoid_address_reuse); const int min_depth = {coinControl ? coinControl->m_min_depth : DEFAULT_MIN_DEPTH}; const int max_depth = {coinControl ? coinControl->m_max_depth : DEFAULT_MAX_DEPTH}; + const bool only_safe = {coinControl ? !coinControl->m_include_unsafe_inputs : true}; std::set<uint256> trusted_parents; for (const auto& entry : mapWallet) @@ -2273,7 +2274,7 @@ void CWallet::AvailableCoins(std::vector<COutput>& vCoins, bool fOnlySafe, const safeTx = false; } - if (fOnlySafe && !safeTx) { + if (only_safe && !safeTx) { continue; } @@ -2843,7 +2844,7 @@ bool CWallet::CreateTransactionInternal( txNew.nLockTime = GetLocktimeForNewTransaction(chain(), GetLastBlockHash(), GetLastBlockHeight()); { std::vector<COutput> vAvailableCoins; - AvailableCoins(vAvailableCoins, !coin_control.m_include_unsafe_inputs, &coin_control, 1, MAX_MONEY, MAX_MONEY, 0); + AvailableCoins(vAvailableCoins, &coin_control, 1, MAX_MONEY, MAX_MONEY, 0); CoinSelectionParams coin_selection_params; // Parameters for coin selection, init with dummy coin_selection_params.m_avoid_partial_spends = coin_control.m_avoid_partial_spends; diff --git a/src/wallet/wallet.h b/src/wallet/wallet.h index 03adca7a89..5a36d92784 100644 --- a/src/wallet/wallet.h +++ b/src/wallet/wallet.h @@ -850,7 +850,7 @@ public: /** * populate vCoins with vector of available COutputs. */ - void AvailableCoins(std::vector<COutput>& vCoins, bool fOnlySafe = true, const CCoinControl* coinControl = nullptr, const CAmount& nMinimumAmount = 1, const CAmount& nMaximumAmount = MAX_MONEY, const CAmount& nMinimumSumAmount = MAX_MONEY, const uint64_t nMaximumCount = 0) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); + void AvailableCoins(std::vector<COutput>& vCoins, const CCoinControl* coinControl = nullptr, const CAmount& nMinimumAmount = 1, const CAmount& nMaximumAmount = MAX_MONEY, const CAmount& nMinimumSumAmount = MAX_MONEY, const uint64_t nMaximumCount = 0) const EXCLUSIVE_LOCKS_REQUIRED(cs_wallet); /** * Return list of available coins and locked coins grouped by non-change output address. |