Skip to content

Conversation

achow101
Copy link
Member

When migratewallet fails, we do an automatic cleanup in order to reset everything so that the user does not experience any interruptions. However, this apparently has a segfault in it, caused by the the pointers to the watchonly and solvables wallets being nullptr. If those wallets are not created (either not needed, or failed early on), we will accidentally attempt to dereference these nullptrs, which causes a segfault.

This failure can be easily reached by trying to migrate an encrypted wallet. Currently, we can't migrate encrypted wallets because of how we unload wallets before migrating, and therefore forget the encryption key if the wallet was unlocked. So any encrypted wallets will fail, entering the cleanup, and because watchonly and solvables wallets don't exist yet, the segfault is reached.

This PR fixes this by not putting those nullptrs in a place that we will end up dereferencing them later. It also adds a test that uses the encrypted wallet issue.

@DrahtBot
Copy link
Contributor

DrahtBot commented Nov 28, 2022

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

Reviews

See the guideline for information on the review process.

Type Reviewers
ACK stickies-v, furszy, S3RK
Concept ACK shaavan
Stale ACK luke-jr

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

Conflicts

Reviewers, this pull request conflicts with the following ones:

  • #26596 (wallet: Migrate legacy wallets to descriptor wallets without requiring BDB by achow101)
  • #26595 (wallet: be able to specify a wallet name and passphrase to migratewallet by achow101)
  • #25722 (refactor: Use util::Result class for wallet loading by ryanofsky)

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.

@achow101 achow101 force-pushed the fix-migratewallet-cleanup-segfault branch 3 times, most recently from 120d8ca to 91c935a Compare November 29, 2022 00:33
@S3RK
Copy link
Contributor

S3RK commented Nov 29, 2022

tACK 91c935a

I think this should be backported to 24.x with a better error message saying that encrypted wallets will be supported in the future.

@fanquake fanquake added this to the 24.0.1 milestone Nov 29, 2022
Copy link
Contributor

@stickies-v stickies-v left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approach ACK 91c935a - not very familiar with the wallet migration process but this looks like an appropriate bug fix approach to me.

Copy link
Contributor

@shaavan shaavan left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Concept ACK

  • The bug fix seems conceptually correct.
  • The test correctly works and captures the correct working of this part of the code. I ran the test on the master, and it failed, as expected.

@achow101 achow101 force-pushed the fix-migratewallet-cleanup-segfault branch 2 times, most recently from 5bb48c9 to 7d7d02f Compare November 29, 2022 19:35
Copy link
Contributor

@stickies-v stickies-v left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 7d7d02f

@achow101
Copy link
Member Author

I think this should be backported to 24.x with a better error message saying that encrypted wallets will be supported in the future.

I've added a commit for an explicit error message saying so.

If migratewallet fails, we do a cleanup which removes the watchonly and
solvables wallets if they were created. However, if they were not, their
pointers are nullptr and we don't check for that, which causes a
segfault during the cleanup. So check that they aren't nullptr before
cleaning them up.
Due to an oversight, we cannot currently migrate encrypted wallets,
regardless of whether they are unlocked. Migrating such wallets will
trigger an error, and result in the cleanup being run. This conveniently
allows us to check some parts of the cleanup code.
Copy link
Member

@luke-jr luke-jr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

utACK 0c340e9

Copy link
Member

@furszy furszy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code review ACK 0c340e9.
Will re-ACK it if you decide to change the RPC error code too.

@achow101 achow101 force-pushed the fix-migratewallet-cleanup-segfault branch from 0c340e9 to 5e65a21 Compare November 30, 2022 15:31
Copy link
Contributor

@stickies-v stickies-v left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK 5e65a21

Copy link
Member

@furszy furszy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

diff ACK 5e65a21

@S3RK
Copy link
Contributor

S3RK commented Nov 30, 2022

reACK 5e65a21

@fanquake fanquake merged commit e334f7a into bitcoin:master Dec 1, 2022
fanquake pushed a commit to fanquake/bitcoin that referenced this pull request Dec 1, 2022
If migratewallet fails, we do a cleanup which removes the watchonly and
solvables wallets if they were created. However, if they were not, their
pointers are nullptr and we don't check for that, which causes a
segfault during the cleanup. So check that they aren't nullptr before
cleaning them up.

Github-Pull: bitcoin#26594
Rebased-From: 86ef7b3
fanquake pushed a commit to fanquake/bitcoin that referenced this pull request Dec 1, 2022
Due to an oversight, we cannot currently migrate encrypted wallets,
regardless of whether they are unlocked. Migrating such wallets will
trigger an error, and result in the cleanup being run. This conveniently
allows us to check some parts of the cleanup code.

Github-Pull: bitcoin#26594
Rebased-From: 88afc73
fanquake pushed a commit to fanquake/bitcoin that referenced this pull request Dec 1, 2022
@fanquake
Copy link
Member

fanquake commented Dec 1, 2022

Backported in #26616.

sidhujag pushed a commit to syscoin/syscoin that referenced this pull request Dec 1, 2022
…e cleanup

5e65a21 wallet: Explicitly say migratewallet on encrypted wallets is unsupported (Andrew Chow)
88afc73 tests: Test for migrating encrypted wallets (Andrew Chow)
86ef7b3 wallet: Avoid null pointer deref when cleaning up migratewallet (Andrew Chow)

Pull request description:

  When `migratewallet` fails, we do an automatic cleanup in order to reset everything so that the user does not experience any interruptions. However, this apparently has a segfault in it, caused by the the pointers to the watchonly and solvables wallets being nullptr. If those wallets are not created (either not needed, or failed early on), we will accidentally attempt to dereference these nullptrs, which causes a segfault.

  This failure can be easily reached by trying to migrate an encrypted wallet. Currently, we can't migrate encrypted wallets because of how we unload wallets before migrating, and therefore forget the encryption key if the wallet was unlocked. So any encrypted wallets will fail, entering the cleanup, and because watchonly and solvables wallets don't exist yet, the segfault is reached.

  This PR fixes this by not putting those nullptrs in a place that we will end up dereferencing them later. It also adds a test that uses the encrypted wallet issue.

ACKs for top commit:
  S3RK:
    reACK 5e65a21
  stickies-v:
    ACK [5e65a21](bitcoin@5e65a21)
  furszy:
    diff ACK 5e65a21

Tree-SHA512: f75643797220d4232ad3ab8cb4b46d0f3667f00486e910ca748c9b6d174d446968f1ec4dd7f907da1be9566088849da7edcd8cd8f12de671c3241b513deb8e80
maflcko pushed a commit that referenced this pull request Dec 6, 2022
8b726bf test: Coin Selection, duplicated preset inputs selection (furszy)
9d73176 test: wallet, coverage for CoinsResult::Erase function (furszy)
195f0df wallet: bugfix, 'CoinsResult::Erase' is erasing only one output of the set (furszy)
e5d097b [test] Add p2p_tx_privacy.py (dergoegge)
c842670 [net processing] Assume that TxRelay::m_tx_inventory_to_send is empty pre-verack (dergoegge)
e15b306 [net processing] Ensure transaction announcements are only queued for fully connected peers (dergoegge)
95fded1 wallet: Explicitly say migratewallet on encrypted wallets is unsupported (Andrew Chow)
d464b2a tests: Test for migrating encrypted wallets (Andrew Chow)
7a97a56 wallet: Avoid null pointer deref when cleaning up migratewallet (Andrew Chow)

Pull request description:

  Backports remaining changes on the 24.0.1 milestone.

  Currently backports:
  * #26594
  * #26569
  * #26560

ACKs for top commit:
  josibake:
    ACK 8b726bf

Tree-SHA512: db77ec1a63a7b6a4412750a0f4c0645681fc346a5df0a7cd38d5d27384e1d0fa95f3953af90042afe131ddbd4b6a6e009527095f13e9f58c0190cd378738a9e5
@bitcoin bitcoin locked and limited conversation to collaborators Dec 27, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

9 participants