Wallet: Zero out wallet master key upon locking so it doesn't persist in memory #27080

pull john-moffett wants to merge 1 commits into bitcoin:master from john-moffett:2023_02_WipeMasterKeyOnLock changing 1 files +5 −1
  1. john-moffett commented at 9:43 PM on February 10, 2023: contributor

    When an encrypted wallet is locked (for instance via the RPC walletlock), the documentation indicates that the key is removed from memory:

    https://github.com/bitcoin/bitcoin/blob/b92d609fb25637ccda000e182da854d4b762eee9/src/wallet/rpc/encrypt.cpp#L157-L158

    However, the vector (a std::vector<unsigned char, secure_allocator<unsigned char>>) is merely cleared. As it is a member variable, it also stays in scope as long as the wallet is loaded, preventing the secure allocator from deallocating. This allows the key to persist indefinitely in memory. I confirmed this behavior on my macOS machine by using an open-source third party memory inspector ("Bit Slicer"). I was able to find my wallet's master key in Bit Slicer after unlocking and re-locking my encrypted wallet. I then confirmed the key data was at the address in LLDB.

    This PR manually fills the bytes with zeroes before calling clear() by using our memory_cleanse function, which is designed to prevent the compiler from optimizing it away. I confirmed that it does remove the data from memory on my machine upon locking.

    Note: An alternative approach could be to call vMasterKey.shrink_to_fit() after the clear(), which would trigger the secure allocator's deallocation. However, shrink_to_fit() is not guaranteed to actually change the vector's capacity, so I think it's unwise to rely on it.

    Edit: A little more clarity on why this is an improvement.

    Since mlocked memory is guaranteed not to be swapped to disk and our threat model doesn't consider a super-user monitoring the memory in realtime, why is this an improvement? Most importantly, consider hibernation. Even mlocked memory may get written to disk. From the mlock manpage:

    (But be aware that the suspend mode on laptops and some desktop computers will save a copy of the system's RAM to disk, regardless of memory locks.)

    As far as I can tell, this is true of Windows and macOS as well.

    Therefore, a user with a strong OS password and a strong wallet passphrase could still have their keys stolen if a thief takes their (hibernated) machine and reads the permanent storage.

  2. DrahtBot commented at 9:43 PM on February 10, 2023: contributor

    <!--e57a25ab6845829454e8d69fc972939a-->

    The following sections might be updated with supplementary metadata relevant to reviewers and maintainers.

    <!--021abf342d371248e50ceaed478a90ca-->

    Reviews

    See the guideline for information on the review process.

    Type Reviewers
    ACK S3RK, achow101

    If your review is incorrectly listed, please react with 👎 to this comment and the bot will ignore it on the next update.

    <!--174a7506f384e20aa4161008e828411d-->

    Conflicts

    Reviewers, this pull request conflicts with the following ones:

    • #26347 (wallet: ensure the wallet is unlocked when needed for rescanning by ishaanam)

    If you consider this pull request important, please also help to review the conflicting pull requests. Ideally, start with the one that should be merged first.

  3. DrahtBot added the label Wallet on Feb 10, 2023
  4. Zero out wallet master key upon lock
    When an encrypted wallet is locked (for instance via the
    RPC `walletlock`), the docs indicate that the key is
    removed from memory. However, the vector (with a secure
    allocator) is merely cleared. This allows the key to persist
    indefinitely in memory. Instead, manually fill the bytes with
    zeroes before clearing.
    3a11adc700
  5. john-moffett force-pushed on Feb 11, 2023
  6. S3RK commented at 7:41 AM on February 13, 2023: contributor

    Code review ACK 3a11adc7004d21b3dfe028b190d83add31691c55

  7. fanquake requested review from achow101 on Feb 13, 2023
  8. achow101 commented at 8:08 PM on February 13, 2023: member

    ACK 3a11adc7004d21b3dfe028b190d83add31691c55

  9. achow101 merged this on Feb 13, 2023
  10. achow101 closed this on Feb 13, 2023

  11. sidhujag referenced this in commit 149cd119b0 on Feb 14, 2023
  12. fanquake commented at 10:15 AM on February 14, 2023: member

    Added this to #26878 for backporting to 24.x.

  13. fanquake referenced this in commit 40ca6e34ca on Feb 14, 2023
  14. fanquake referenced this in commit 64e7db6f4f on Feb 22, 2023
  15. glozow referenced this in commit c8c85ca16e on Feb 27, 2023
  16. Fabcien referenced this in commit 05238e31ba on Mar 14, 2023
  17. bitcoin locked this on Feb 14, 2024

github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-04-15 00:13 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me