Skip to content

client/db/bolt: fix data corruption from reused buffers#561

Merged
chappjc merged 1 commit into
decred:masterfrom
chappjc:bolt-slice-reuse
Jul 23, 2020
Merged

client/db/bolt: fix data corruption from reused buffers#561
chappjc merged 1 commit into
decred:masterfrom
chappjc:bolt-slice-reuse

Conversation

@chappjc
Copy link
Copy Markdown
Member

@chappjc chappjc commented Jul 22, 2020

The returned byte slice from bbolt.(*Bucket).Get is not valid outside of
the transaction where it is used. This change fixes several places
where the []byte was used outside of the transaction without copying it,
resulting in mysteriously corrupted data, including ChangeCoin.

Add the client/db/bolt.getCopy function to load a value and make a copy.
If the loaded value is an empty slice, it returns nil. Thus, to
identify a non-existent value, use Bucket.Get directly instead.
getCopy covers most of the cases where we want to get the value into a
slice that is safe to use outside of a transaction, and when we do not
wish to load an empty non-nil slice when nil was actually stored.

Notably, this fixes decodeOrderBucket, DecodeMatchProof, and
makeWallet>DecodeWallet (keyB).

Likely resolves the "btc coin 0000000000000000000000000000000000000000000000000000000000000000:0 not found " issue reported in #531 (review). I reproduced the issue with a different but equally impossible coin id of 00000000000000000000000000000000000000000000002a000000516b444b63:131074 after starting dexc with an active match in TakerSwapCast and following that with new matches.

The returned byte slice from bbolt.(*Bucket).Get is not valid outside of
the transaction where it is used.  This change fixes several places
where the []byte was used without copying it, resulting in corrupted
data.

Add the client/db/bolt.getCopy function to load a value and make a copy.
If the loaded value is an empty slice, it returns nil.  Thus, to
identify a non-existent value, use Bucket.Get directly instead.
getCopy covers most of the cases where we want to get the value in a
slice that is safe to use outside of a transaction, and when we do not
wish to load an empty non-nil slice when nil was actually stored.

Notably, this fixes decodeOrderBucket, and possibly filteredMatches,
makeWallet, and NotificationsN.
@chappjc chappjc merged commit d0ef57a into decred:master Jul 23, 2020
@chappjc chappjc deleted the bolt-slice-reuse branch July 23, 2020 14:13
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants