Support for wallets outside of the default wallet directory was added in #11687, and these external wallets can be specified with paths relative to the wallet directory, e.g. bitcoin-cli loadwallet ../../mywallet
. In the RPC commands, there is no distinction between a wallet’s ’name’ and a wallet’s ‘path’. This PR fixes an issue with wallet backup during migration where the wallet’s ’name-path’ is used in the backup filename. This goes south when that filename is appended to the directory where we want to put the file and the wallet’s ’name’ actually gets treated as a path:
0 fs::path backup_filename = fs::PathFromString(strprintf("%s_%d.legacy.bak", (wallet_name.empty() ? "default_wallet" : wallet_name), GetTime()));
1 fs::path backup_path = this_wallet_dir / backup_filename;
Attempting to migrate a wallet with the ’name’ ../../../mywallet
results in a backup being placed in datadir/wallets/../../../mywallet/../../../mywallet_1744683963.legacy.bak
.
If permissions don’t exist to write to that folder, migration can fail.
The solution implemented here is to reuse the path parsing logic used during wallet loading in CWallet::GetWalletPath()
:
And to split up the handling of direct file wallets and normal wallets:
0 std::string legacy_wallet_dir_name = fs::PathToString(legacy_wallet_dir.filename());
1 fs::path backup_filename = fs::PathFromString(strprintf("%s_%d.legacy.bak", (wallet_name.empty() ? "default_wallet" : legacy_wallet_dir_name), GetTime()));
Steps to reproduce on master
Build and run bitcoind
with legacy wallet creation enabled:
0$ cmake -B build -DWITH_BDB=ON && cmake --build build -j $(nproc)
1$ ./build/bin/bitcoind -regtest -deprecatedrpc=create_bdb
Create a wallet with some relative path specifiers (exercise caution with where this file may be written)
0$ ./build/bin/bitcoin-cli -regtest -named createwallet wallet_name="../../../myrelativewallet" descriptors=false
Try to migrate the wallet:
0$ ./build/bin/bitcoin-cli -regtest -named migratewallet wallet_name="../../../myrelativewallet"
You will see a message in debug.log
about trying to backup a file somewhere like: /home/user/.bitcoin/regtest/wallets/../../../myrelativewallet/../../../myrelativewallet_1744686627.legacy.bak
and migration might fail because bitcoind
doesn’t have permissions to write the backup file.