aboutsummaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorpracticalswift <practicalswift@users.noreply.github.com>2021-10-01 13:53:59 +0000
committerpracticalswift <practicalswift@users.noreply.github.com>2021-10-01 13:51:10 +0000
commit4747da3a5b639b5a336b737e7e3cbf060cf2efcf (patch)
treec375c8eff3a7f4b02f66247b52dfee286e7fcbae /test
parente69cbac628bfdca4a8e4ead821190eaf5b6b3d07 (diff)
downloadbitcoin-4747da3a5b639b5a336b737e7e3cbf060cf2efcf.tar.xz
Add syscall sandboxing (seccomp-bpf)
Diffstat (limited to 'test')
-rw-r--r--test/config.ini.in1
-rwxr-xr-xtest/functional/feature_notifications.py3
-rwxr-xr-xtest/functional/feature_syscall_sandbox.py34
-rwxr-xr-xtest/functional/feature_versionbits_warning.py3
-rwxr-xr-xtest/functional/rpc_misc.py2
-rwxr-xr-xtest/functional/rpc_signer.py3
-rwxr-xr-xtest/functional/test_framework/test_framework.py11
-rwxr-xr-xtest/functional/test_runner.py1
-rwxr-xr-xtest/functional/wallet_signer.py3
9 files changed, 60 insertions, 1 deletions
diff --git a/test/config.ini.in b/test/config.ini.in
index db80bba6f1..8bcba1b39c 100644
--- a/test/config.ini.in
+++ b/test/config.ini.in
@@ -24,3 +24,4 @@ RPCAUTH=@abs_top_srcdir@/share/rpcauth/rpcauth.py
@ENABLE_FUZZ_TRUE@ENABLE_FUZZ=true
@ENABLE_ZMQ_TRUE@ENABLE_ZMQ=true
@ENABLE_EXTERNAL_SIGNER_TRUE@ENABLE_EXTERNAL_SIGNER=true
+@ENABLE_SYSCALL_SANDBOX_TRUE@ENABLE_SYSCALL_SANDBOX=true
diff --git a/test/functional/feature_notifications.py b/test/functional/feature_notifications.py
index 5ef3860867..48d41432be 100755
--- a/test/functional/feature_notifications.py
+++ b/test/functional/feature_notifications.py
@@ -27,6 +27,9 @@ class NotificationsTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 2
self.setup_clean_chain = True
+ # The experimental syscall sandbox feature (-sandbox) is not compatible with -alertnotify,
+ # -blocknotify or -walletnotify (which all invoke execve).
+ self.disable_syscall_sandbox = True
def setup_network(self):
self.wallet = ''.join(chr(i) for i in range(FILE_CHAR_START, FILE_CHAR_END) if chr(i) not in FILE_CHARS_DISALLOWED)
diff --git a/test/functional/feature_syscall_sandbox.py b/test/functional/feature_syscall_sandbox.py
new file mode 100755
index 0000000000..caf7f1e7fc
--- /dev/null
+++ b/test/functional/feature_syscall_sandbox.py
@@ -0,0 +1,34 @@
+#!/usr/bin/env python3
+# Copyright (c) 2021 The Bitcoin Core developers
+# Distributed under the MIT software license, see the accompanying
+# file COPYING or http://www.opensource.org/licenses/mit-license.php.
+"""Test bitcoind aborts if a disallowed syscall is used when compiled with the syscall sandbox."""
+
+from test_framework.test_framework import BitcoinTestFramework, SkipTest
+
+
+class SyscallSandboxTest(BitcoinTestFramework):
+ def set_test_params(self):
+ self.num_nodes = 1
+
+ def skip_test_if_missing_module(self):
+ if not self.is_syscall_sandbox_compiled():
+ raise SkipTest("bitcoind has not been built with syscall sandbox enabled.")
+ if self.options.nosandbox:
+ raise SkipTest("--nosandbox passed to test runner.")
+
+ def run_test(self):
+ disallowed_syscall_terminated_bitcoind = False
+ expected_log_entry = 'ERROR: The syscall "getgroups" (syscall number 115) is not allowed by the syscall sandbox'
+ with self.nodes[0].assert_debug_log([expected_log_entry]):
+ self.log.info("Invoking disallowed syscall")
+ try:
+ self.nodes[0].invokedisallowedsyscall()
+ except ConnectionError:
+ disallowed_syscall_terminated_bitcoind = True
+ assert disallowed_syscall_terminated_bitcoind
+ self.nodes = []
+
+
+if __name__ == "__main__":
+ SyscallSandboxTest().main()
diff --git a/test/functional/feature_versionbits_warning.py b/test/functional/feature_versionbits_warning.py
index 311d871d49..d74ef5e088 100755
--- a/test/functional/feature_versionbits_warning.py
+++ b/test/functional/feature_versionbits_warning.py
@@ -28,6 +28,9 @@ class VersionBitsWarningTest(BitcoinTestFramework):
def set_test_params(self):
self.setup_clean_chain = True
self.num_nodes = 1
+ # The experimental syscall sandbox feature (-sandbox) is not compatible with -alertnotify
+ # (which invokes execve).
+ self.disable_syscall_sandbox = True
def setup_network(self):
self.alert_filename = os.path.join(self.options.tmpdir, "alert.txt")
diff --git a/test/functional/rpc_misc.py b/test/functional/rpc_misc.py
index 13f33c321f..ac2a7a309b 100755
--- a/test/functional/rpc_misc.py
+++ b/test/functional/rpc_misc.py
@@ -57,7 +57,7 @@ class RpcMiscTest(BitcoinTestFramework):
self.log.info("test logging rpc and help")
# Test logging RPC returns the expected number of logging categories.
- assert_equal(len(node.logging()), 25)
+ assert_equal(len(node.logging()), 26)
# Test toggling a logging category on/off/on with the logging RPC.
assert_equal(node.logging()['qt'], True)
diff --git a/test/functional/rpc_signer.py b/test/functional/rpc_signer.py
index 9e963eba57..5c3722ef8f 100755
--- a/test/functional/rpc_signer.py
+++ b/test/functional/rpc_signer.py
@@ -27,6 +27,9 @@ class RPCSignerTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 4
+ # The experimental syscall sandbox feature (-sandbox) is not compatible with -signer (which
+ # invokes execve).
+ self.disable_syscall_sandbox = True
self.extra_args = [
[],
diff --git a/test/functional/test_framework/test_framework.py b/test/functional/test_framework/test_framework.py
index f382e0fdb3..0fad4071e2 100755
--- a/test/functional/test_framework/test_framework.py
+++ b/test/functional/test_framework/test_framework.py
@@ -101,6 +101,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
self.supports_cli = True
self.bind_to_localhost_only = True
self.parse_args()
+ self.disable_syscall_sandbox = self.options.nosandbox
self.default_wallet_name = "default_wallet" if self.options.descriptors else ""
self.wallet_data_filename = "wallet.dat"
# Optional list of wallet names that can be set in set_test_params to
@@ -159,6 +160,8 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
parser = argparse.ArgumentParser(usage="%(prog)s [options]")
parser.add_argument("--nocleanup", dest="nocleanup", default=False, action="store_true",
help="Leave bitcoinds and test.* datadir on exit or error")
+ parser.add_argument("--nosandbox", dest="nosandbox", default=False, action="store_true",
+ help="Don't use the syscall sandbox")
parser.add_argument("--noshutdown", dest="noshutdown", default=False, action="store_true",
help="Don't stop bitcoinds after the test execution")
parser.add_argument("--cachedir", dest="cachedir", default=os.path.abspath(os.path.dirname(os.path.realpath(__file__)) + "/../../cache"),
@@ -468,6 +471,10 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
extra_args = [[]] * num_nodes
if versions is None:
versions = [None] * num_nodes
+ if self.is_syscall_sandbox_compiled() and not self.disable_syscall_sandbox:
+ for i in range(len(extra_args)):
+ if versions[i] is None or versions[i] >= 219900:
+ extra_args[i] = extra_args[i] + ["-sandbox=log-and-abort"]
if binary is None:
binary = [get_bin_from_version(v, 'bitcoind', self.options.bitcoind) for v in versions]
if binary_cli is None:
@@ -886,3 +893,7 @@ class BitcoinTestFramework(metaclass=BitcoinTestMetaClass):
def is_bdb_compiled(self):
"""Checks whether the wallet module was compiled with BDB support."""
return self.config["components"].getboolean("USE_BDB")
+
+ def is_syscall_sandbox_compiled(self):
+ """Checks whether the syscall sandbox was compiled."""
+ return self.config["components"].getboolean("ENABLE_SYSCALL_SANDBOX")
diff --git a/test/functional/test_runner.py b/test/functional/test_runner.py
index 3792d751de..c5af10430c 100755
--- a/test/functional/test_runner.py
+++ b/test/functional/test_runner.py
@@ -170,6 +170,7 @@ BASE_SCRIPTS = [
'rpc_users.py',
'rpc_whitelist.py',
'feature_proxy.py',
+ 'feature_syscall_sandbox.py',
'rpc_signrawtransaction.py --legacy-wallet',
'rpc_signrawtransaction.py --descriptors',
'rpc_rawtransaction.py --legacy-wallet',
diff --git a/test/functional/wallet_signer.py b/test/functional/wallet_signer.py
index 7b77755d64..c6c1cc8784 100755
--- a/test/functional/wallet_signer.py
+++ b/test/functional/wallet_signer.py
@@ -27,6 +27,9 @@ class WalletSignerTest(BitcoinTestFramework):
def set_test_params(self):
self.num_nodes = 2
+ # The experimental syscall sandbox feature (-sandbox) is not compatible with -signer (which
+ # invokes execve).
+ self.disable_syscall_sandbox = True
self.extra_args = [
[],