AI-generated analysisPublished automatically and not human-verified. Validated context appears in community notes below.
← Watch feed
Low 45 Bitcoin

Merge bitcoin/bitcoin#35440: wallet: check descriptor cache xpub length before decoding

Public commit record

What the developer wrote

Authored by Ava Chow

96/100 · Strong
Merge bitcoin/bitcoin#35440: wallet: check descriptor cache xpub length before decoding

db7ec4fb976284581ba2adc77218af8711375d91 refactor: (de)serialize CExtKey/CExtPubKey through streams (Alhuda Khan)
cb69853fc160d8a02c21510b8251b05913665672 wallet: check descriptor cache xpub length before decoding (alhudz)

Pull request description:

The descriptor cache records (`WALLETDESCRIPTORCACHE`/`WALLETDESCRIPTORLHCACHE`) deserialise their value into a vector whose length comes from the record itself, but `CExtPubKey::Decode` then reads a fixed `BIP32_EXTKEY_SIZE` bytes. A record encoding a shorter xpub makes `Decode` read past the vector (caught as a container-overflow under ASan).

The first commit rejects records whose serialised xpub isn't exactly `BIP32_EXTKEY_SIZE`, the same way the other malformed records in this loader return `DBErrors::CORRUPT`, with a unit test covering both cache types.

The second commit (per https://github.com/bitcoin/bitcoin/pull/35440#issuecomment-5050992564) replaces `CExtKey`/`CExtPubKey` `Encode`/`Decode` and `EncodeWithVersion`/`DecodeWithVersion`, the only (de)serialisation in the codebase that wrote into a caller-provided buffer, with `Serialize`/`Unserialize`, and routes the base58, PSBT and wallet cache code through them. The serialised bytes are unchanged, so base58 and PSBT encodings and the on-disk cache records are the same as before. The wallet loader now checks the record's CompactSize prefix and reads the xpub straight from the record stream.

ACKs for top commit:
molnard:
tACK db7ec4fb976284581ba2adc77218af8711375d91
achow101:
ACK db7ec4fb976284581ba2adc77218af8711375d91
winterrdog:
tACK db7ec4fb976284581ba2adc77218af8711375d91

Tree-SHA512: e315d1c0e0d542643dc286055fcbe7b1f98891c8dff844cc55888bb970c3147e2b35fc3c0103e9a55101c6820e8bb5817316a5048e3c4e2c548ce30345eaa3a0
✓ Specific, descriptive subject✓ Names a concrete action or component✓ Provides detailed explanatory context✓ Mentions testing or verification✓ Links an issue, advisory, or supporting reference✓ Names security-relevant behavior explicitly
The short version

What changed, and why it matters

This update fixes a wallet database loading bug where a damaged or tampered Bitcoin wallet file could cause the program to read past the end of a stored extended public key (xpub). The patch makes the loader check the stored xpub length before decoding it, and also replaces the old fixed-size buffer encoding with safer stream-based serialization used throughout the rest of the code. It is primarily a hardening fix against corrupt wallet data rather than a remote attack vector.

Recommended action

Treat this as a wallet data-integrity hardening fix. Users should upgrade to a release containing this patch, especially if they rely on descriptor wallets, and avoid opening wallet files from untrusted sources. Developers should verify that any custom tools writing descriptor cache records use the exact BIP32_EXTKEY_SIZE serialization.

Security signals we found

01

Out-of-bounds read in wallet descriptor cache deserialization

02

ASan container-overflow triggered by malformed on-disk record

03

Missing length validation between record size prefix and fixed-size decoder

04

Refactor of manual buffer Encode/Decode to stream-based Serialize/Unserialize

05

Unit tests added for short xpub cache records and invalid deserialization inputs

Risk score

Why this scored 45/100

Our methodology →
Potential impact 12/30
Exploitability 8/25
Stealth signal 7/15
Affected reach 6/15
Confidence 8/10
Evidence quality 4/5
Human-validated context

Community notes

Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.

No validated notes yet.

The AI analysis stands alone for now. Submit a note if you can add evidence or important context.