aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xcontrib/devtools/security-check.py7
-rwxr-xr-xcontrib/devtools/test-security-check.py16
-rw-r--r--src/qt/bitcoin.cpp31
-rwxr-xr-xtest/functional/p2p_permissions.py28
-rwxr-xr-xtest/functional/wallet_importdescriptors.py4
5 files changed, 38 insertions, 48 deletions
diff --git a/contrib/devtools/security-check.py b/contrib/devtools/security-check.py
index 336e2c9e2e..8377b92736 100755
--- a/contrib/devtools/security-check.py
+++ b/contrib/devtools/security-check.py
@@ -146,6 +146,12 @@ def check_PE_control_flow(binary) -> bool:
return True
return False
+def check_PE_Canary(binary) -> bool:
+ '''
+ Check for use of stack canary
+ '''
+ return binary.has_symbol('__stack_chk_fail')
+
def check_MACHO_NOUNDEFS(binary) -> bool:
'''
Check for no undefined references.
@@ -203,6 +209,7 @@ BASE_PE = [
('NX', check_NX),
('RELOC_SECTION', check_PE_RELOC_SECTION),
('CONTROL_FLOW', check_PE_control_flow),
+ ('Canary', check_PE_Canary),
]
BASE_MACHO = [
diff --git a/contrib/devtools/test-security-check.py b/contrib/devtools/test-security-check.py
index 6e0e0ae1b5..fe61ab275f 100755
--- a/contrib/devtools/test-security-check.py
+++ b/contrib/devtools/test-security-check.py
@@ -94,19 +94,19 @@ class TestSecurityChecks(unittest.TestCase):
cc = determine_wellknown_cmd('CC', 'x86_64-w64-mingw32-gcc')
write_testcode(source)
- self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--disable-nxcompat','-Wl,--disable-reloc-section','-Wl,--disable-dynamicbase','-Wl,--disable-high-entropy-va','-no-pie','-fno-PIE']),
- (1, executable+': failed PIE DYNAMIC_BASE HIGH_ENTROPY_VA NX RELOC_SECTION CONTROL_FLOW'))
- self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--disable-reloc-section','-Wl,--disable-dynamicbase','-Wl,--disable-high-entropy-va','-no-pie','-fno-PIE']),
+ self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--disable-nxcompat','-Wl,--disable-reloc-section','-Wl,--disable-dynamicbase','-Wl,--disable-high-entropy-va','-no-pie','-fno-PIE','-fno-stack-protector']),
+ (1, executable+': failed PIE DYNAMIC_BASE HIGH_ENTROPY_VA NX RELOC_SECTION CONTROL_FLOW Canary'))
+ self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--disable-reloc-section','-Wl,--disable-dynamicbase','-Wl,--disable-high-entropy-va','-no-pie','-fno-PIE','-fstack-protector-all', '-lssp']),
(1, executable+': failed PIE DYNAMIC_BASE HIGH_ENTROPY_VA RELOC_SECTION CONTROL_FLOW'))
- self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--enable-reloc-section','-Wl,--disable-dynamicbase','-Wl,--disable-high-entropy-va','-no-pie','-fno-PIE']),
+ self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--enable-reloc-section','-Wl,--disable-dynamicbase','-Wl,--disable-high-entropy-va','-no-pie','-fno-PIE','-fstack-protector-all', '-lssp']),
(1, executable+': failed PIE DYNAMIC_BASE HIGH_ENTROPY_VA CONTROL_FLOW'))
- self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--enable-reloc-section','-Wl,--disable-dynamicbase','-Wl,--disable-high-entropy-va','-pie','-fPIE']),
+ self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--enable-reloc-section','-Wl,--disable-dynamicbase','-Wl,--disable-high-entropy-va','-pie','-fPIE','-fstack-protector-all', '-lssp']),
(1, executable+': failed PIE DYNAMIC_BASE HIGH_ENTROPY_VA CONTROL_FLOW')) # -pie -fPIE does nothing unless --dynamicbase is also supplied
- self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--enable-reloc-section','-Wl,--dynamicbase','-Wl,--disable-high-entropy-va','-pie','-fPIE']),
+ self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--enable-reloc-section','-Wl,--dynamicbase','-Wl,--disable-high-entropy-va','-pie','-fPIE','-fstack-protector-all', '-lssp']),
(1, executable+': failed HIGH_ENTROPY_VA CONTROL_FLOW'))
- self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--enable-reloc-section','-Wl,--dynamicbase','-Wl,--high-entropy-va','-pie','-fPIE']),
+ self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--enable-reloc-section','-Wl,--dynamicbase','-Wl,--high-entropy-va','-pie','-fPIE','-fstack-protector-all', '-lssp']),
(1, executable+': failed CONTROL_FLOW'))
- self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--enable-reloc-section','-Wl,--dynamicbase','-Wl,--high-entropy-va','-pie','-fPIE', '-fcf-protection=full']),
+ self.assertEqual(call_security_check(cc, source, executable, ['-Wl,--nxcompat','-Wl,--enable-reloc-section','-Wl,--dynamicbase','-Wl,--high-entropy-va','-pie','-fPIE', '-fcf-protection=full','-fstack-protector-all', '-lssp']),
(0, ''))
clean_files(source, executable)
diff --git a/src/qt/bitcoin.cpp b/src/qt/bitcoin.cpp
index b6720b0433..e8b07a6749 100644
--- a/src/qt/bitcoin.cpp
+++ b/src/qt/bitcoin.cpp
@@ -592,29 +592,30 @@ int GuiMain(int argc, char* argv[])
// Gracefully exit if the user cancels
if (!Intro::showIfNeeded(did_show_intro, prune_MiB)) return EXIT_SUCCESS;
- /// 6. Determine availability of data directory and parse bitcoin.conf
- /// - Do not call gArgs.GetDataDirNet() before this step finishes
+ /// 6a. Determine availability of data directory
if (!CheckDataDirOption()) {
InitError(strprintf(Untranslated("Specified data directory \"%s\" does not exist.\n"), gArgs.GetArg("-datadir", "")));
QMessageBox::critical(nullptr, PACKAGE_NAME,
QObject::tr("Error: Specified data directory \"%1\" does not exist.").arg(QString::fromStdString(gArgs.GetArg("-datadir", ""))));
return EXIT_FAILURE;
}
- if (!gArgs.ReadConfigFiles(error, true)) {
- InitError(strprintf(Untranslated("Error reading configuration file: %s\n"), error));
- QMessageBox::critical(nullptr, PACKAGE_NAME,
- QObject::tr("Error: Cannot parse configuration file: %1.").arg(QString::fromStdString(error)));
- return EXIT_FAILURE;
- }
+ try {
+ /// 6b. Parse bitcoin.conf
+ /// - Do not call gArgs.GetDataDirNet() before this step finishes
+ if (!gArgs.ReadConfigFiles(error, true)) {
+ InitError(strprintf(Untranslated("Error reading configuration file: %s\n"), error));
+ QMessageBox::critical(nullptr, PACKAGE_NAME,
+ QObject::tr("Error: Cannot parse configuration file: %1.").arg(QString::fromStdString(error)));
+ return EXIT_FAILURE;
+ }
- /// 7. Determine network (and switch to network specific options)
- // - Do not call Params() before this step
- // - Do this after parsing the configuration file, as the network can be switched there
- // - QSettings() will use the new application name after this, resulting in network-specific settings
- // - Needs to be done before createOptionsModel
+ /// 7. Determine network (and switch to network specific options)
+ // - Do not call Params() before this step
+ // - Do this after parsing the configuration file, as the network can be switched there
+ // - QSettings() will use the new application name after this, resulting in network-specific settings
+ // - Needs to be done before createOptionsModel
- // Check for chain settings (Params() calls are only valid after this clause)
- try {
+ // Check for chain settings (Params() calls are only valid after this clause)
SelectParams(gArgs.GetChainName());
} catch(std::exception &e) {
InitError(Untranslated(strprintf("%s\n", e.what())));
diff --git a/test/functional/p2p_permissions.py b/test/functional/p2p_permissions.py
index f8d3fd919d..624e94d8af 100755
--- a/test/functional/p2p_permissions.py
+++ b/test/functional/p2p_permissions.py
@@ -7,30 +7,27 @@
Test that permissions are correctly calculated and applied
"""
-from test_framework.address import ADDRESS_BCRT1_P2WSH_OP_TRUE
from test_framework.messages import (
- CTxInWitness,
- tx_from_hex,
+ SEQUENCE_FINAL,
)
from test_framework.p2p import P2PDataStore
-from test_framework.script import (
- CScript,
- OP_TRUE,
-)
from test_framework.test_node import ErrorMatch
from test_framework.test_framework import BitcoinTestFramework
from test_framework.util import (
assert_equal,
p2p_port,
)
+from test_framework.wallet import MiniWallet
class P2PPermissionsTests(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 2
- self.setup_clean_chain = True
def run_test(self):
+ self.wallet = MiniWallet(self.nodes[0])
+ self.wallet.rescan_utxos()
+
self.check_tx_relay()
self.checkpermission(
@@ -94,8 +91,6 @@ class P2PPermissionsTests(BitcoinTestFramework):
self.nodes[1].assert_start_raises_init_error(["-whitebind=noban@127.0.0.1", "-bind=127.0.0.1", "-listen=0"], "Cannot set -bind or -whitebind together with -listen=0", match=ErrorMatch.PARTIAL_REGEX)
def check_tx_relay(self):
- block_op_true = self.nodes[0].getblock(self.generatetoaddress(self.nodes[0], 100, ADDRESS_BCRT1_P2WSH_OP_TRUE)[0])
-
self.log.debug("Create a connection from a forcerelay peer that rebroadcasts raw txs")
# A test framework p2p connection is needed to send the raw transaction directly. If a full node was used, it could only
# rebroadcast via the inv-getdata mechanism. However, even for forcerelay connections, a full node would
@@ -104,18 +99,7 @@ class P2PPermissionsTests(BitcoinTestFramework):
p2p_rebroadcast_wallet = self.nodes[1].add_p2p_connection(P2PDataStore())
self.log.debug("Send a tx from the wallet initially")
- tx = tx_from_hex(
- self.nodes[0].createrawtransaction(
- inputs=[{
- 'txid': block_op_true['tx'][0],
- 'vout': 0,
- }], outputs=[{
- ADDRESS_BCRT1_P2WSH_OP_TRUE: 5,
- }],
- replaceable=False),
- )
- tx.wit.vtxinwit = [CTxInWitness()]
- tx.wit.vtxinwit[0].scriptWitness.stack = [CScript([OP_TRUE])]
+ tx = self.wallet.create_self_transfer(sequence=SEQUENCE_FINAL)['tx']
txid = tx.rehash()
self.log.debug("Wait until tx is in node[1]'s mempool")
diff --git a/test/functional/wallet_importdescriptors.py b/test/functional/wallet_importdescriptors.py
index 9e813166c5..ca0209b61d 100755
--- a/test/functional/wallet_importdescriptors.py
+++ b/test/functional/wallet_importdescriptors.py
@@ -15,7 +15,6 @@ variants.
- `test_address()` is called to call getaddressinfo for an address on node1
and test the values returned."""
-from test_framework.address import key_to_p2pkh
from test_framework.blocktools import COINBASE_MATURITY
from test_framework.test_framework import BitcoinTestFramework
from test_framework.descriptors import descsum_create
@@ -120,12 +119,11 @@ class ImportDescriptorsTest(BitcoinTestFramework):
self.log.info("Internal addresses should be detected as such")
key = get_generate_key()
- addr = key_to_p2pkh(key.pubkey)
self.test_importdesc({"desc": descsum_create("pkh(" + key.pubkey + ")"),
"timestamp": "now",
"internal": True},
success=True)
- info = w1.getaddressinfo(addr)
+ info = w1.getaddressinfo(key.p2pkh_addr)
assert_equal(info["ismine"], True)
assert_equal(info["ischange"], True)