#34603 wallet: Fix detection of symlinks on Windows
https://github.com/bitcoin/bitcoin/pull/34603 · · +57/-40 in 5 files, 4 commits · labels: Wallet
Goal
- Prevent unintended directory traversal and loops when scanning wallet paths on Windows
- Properly detect symlinks and reparse points despite MinGW runtime limitations
This pull request implements an `IsSymlink` helper in `fs_helpers` that checks for Windows reparse points using `GetFileAttributesW`, working around GCC MinGW's lack of Windows symlink support in `std::filesystem`. It integrates this check into the wallet's `ListDatabases` to prevent recursive scanning of symlinks and into `GetWalletPath` to validate paths properly on Windows, while enabling symlink functional tests for Windows.
Problem: GCC libstdc++ does not detect symlinks on Windows, treating them as regular files or failing to report them. As a result, Windows wallet directory scanning can recurse into symlinked or reparse directories, and path validation fails to catch invalid symlink targets.
Category: Wallet (#47 of 84)
P3 · platform fix
- P3 because it prevents potential directory scan loops for Windows wallet users
- Affects an edge case in Windows multiwallet directory handling, making it deferrable
Prevents potential infinite loops or unintended directory traversals when scanning wallets on Windows by accounting for MinGW's lack of symlink detection. While beneficial for Windows multiwallet reliability, it addresses an edge case and is reasonably deferrable.
Membership: Modifies ListDatabases in src/wallet/db.cpp and GetWalletPath in src/wallet/wallet.cpp, and updates wallet_multiwallet.py.
Factors: security/stability 1, bug 1, performance 0, user value 1, leverage 1
Category: Utilities (logging, arguments, libraries) (#52 of 66)
P4 · platform fix
- P4 because it adds a narrowly scoped platform helper to filesystem utilities
- Benefit is limited to supporting the wallet directory scanning fix
Adds a platform-specific helper in common fs utilities to check for reparse points on Windows. It has a narrow use case tailored specifically to the wallet directory scanning needs.
Membership: Adds IsSymlink helper to src/util/fs_helpers.cpp and src/util/fs_helpers.h.
Factors: security/stability 0, bug 1, performance 0, user value 0, leverage 0
Reviewability: Stale: Author silent
- Author silent for over 100 days
- No merge conflicts or CI failures, code is ready for review
The author has been inactive on the PR for 113 days, exceeding the 60-day project staleness threshold, though there are no merge conflicts or CI failures.
Author status: silent since 2026-05-26
Open concerns:
- sedited suggested clarifying in the PR description why WIN32 is gated in general given MSVC/clang-cl behavior.
Resolved concerns:
- hebasto inquired whether specific reparse point tags should be filtered; achow101 clarified none should be recursively scanned.
- luke-jr questioned whether to override `fs::is_symlink` directly or avoid redundant calls in path validation; achow101 addressed the duplicate call in a push.
Agreement: Positive
- Generally positive sentiment with technical inquiries addressed
- Approved with a minor nonblocking request for description updates (sedited)
- Technical questions on reparse behavior and duplicate calls resolved (hebasto, luke-jr)
Positive; questions regarding Windows reparse tags were answered and the PR has one approval (sedited).
Initial questions around whether to override std::filesystem and how reparse points behave under clang-cl were answered by the author. sedited provided an approval with a minor nonblocking suggestion.
- sedited approved: 'utACK. The changes seem fine to me, but I would suggest adding a note in the description'
- hebasto noted std::filesystem behavior on Windows across compilers
- luke-jr raised questions on double-calling IsSymlink, which were fixed in subsequent pushes
Review verdicts (DrahtBot): 0
- Concept ACK: sedited
Files
66 lines under test/bench/ci.
- test/functional/wallet_multiwallet.py +27/-39
- src/util/fs_helpers.cpp +14/-0
- src/util/fs_helpers.h +7/-0
- src/wallet/db.cpp +6/-0
- src/wallet/wallet.cpp +3/-1
Card
This pull request implements Windows symlink detection in util/fs_helpers using native Windows reparse point attributes, working around GCC libstdc++ limitations on MinGW. It applies this check in the wallet to avoid recursive scanning of symlinks and to correctly validate wallet paths on Windows. The problem affects Windows users who have reparse points or symlinks in their wallet directories. The change has an approval from sedited and resolves earlier questions, but the author has been silent for over 100 days.