From 08925d5ee75c15712f523bacbdcfd44257f9c8ac Mon Sep 17 00:00:00 2001 From: furszy Date: Sat, 3 Jan 2026 12:37:45 -0500 Subject: [PATCH] test: add coverage for loading a wallet in a non-writable directory Previously, wallets in non-writable directories were loaded, leading to crashes on any subsequent write. --- test/functional/wallet_startup.py | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/test/functional/wallet_startup.py b/test/functional/wallet_startup.py index fe35ee12f9e..2c5fb259059 100755 --- a/test/functional/wallet_startup.py +++ b/test/functional/wallet_startup.py @@ -6,12 +6,17 @@ Verify that a bitcoind node can maintain list of wallets loading on startup """ +import os import shutil +import stat import uuid + from test_framework.test_framework import BitcoinTestFramework from test_framework.util import ( assert_equal, + assert_raises_rpc_error, + is_dir_writable, ) @@ -38,6 +43,27 @@ class WalletStartupTest(BitcoinTestFramework): shutil.move(self.nodes[0].wallets_path / wallet_name / "wallet.dat", self.nodes[0].wallets_path / "wallet.dat") (self.nodes[0].wallets_path / wallet_name).rmdir() + def test_load_unwritable_wallet(self, node): + self.log.info("Test wallet load failure due to non-writable directory") + wallet_name = "bad_permissions" + + node.createwallet(wallet_name) + node.unloadwallet(wallet_name) + + dir_path = node.wallets_path / wallet_name + original_dir_perms = dir_path.stat().st_mode + os.chmod(dir_path, original_dir_perms & ~(stat.S_IWUSR | stat.S_IWGRP | stat.S_IWOTH)) + + if is_dir_writable(dir_path): + self.log.warning("Skipping load non-writable directory test: unable to enforce read-only permissions") + else: + # Ensure we don't load a wallet located in a non-writable directory. + # The node will crash later on if we cannot write to disk. + assert_raises_rpc_error(-4, f"SQLiteDatabase: Failed to open database in directory '{str(dir_path)}': directory is not writable", node.loadwallet, wallet_name) + + # Reset directory permissions for cleanup + dir_path.chmod(original_dir_perms) + def run_test(self): self.log.info('Should start without any wallets') assert_equal(self.nodes[0].listwallets(), []) @@ -67,5 +93,7 @@ class WalletStartupTest(BitcoinTestFramework): self.restart_node(0) assert_equal(set(self.nodes[0].listwallets()), set(('w2', 'w3'))) + self.test_load_unwritable_wallet(self.nodes[0]) + if __name__ == '__main__': WalletStartupTest(__file__).main()