-
Notifications
You must be signed in to change notification settings - Fork 38.8k
refactor: Avoid integer overflow in ApplyStats when activating snapshot #23411
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
31ce7b3 to
fac215e
Compare
fac215e to
fa5bdc9
Compare
|
How does activating a snapshot trigger an integer overflow in this code in the first place? That seems far more concerning, and this PR just patches it up. |
|
@sipa Added three more sentences to OP to explain this refactor. |
|
Hm, I'm kind of confused - is the concern here that a user could be fed a bad snapshot that causes an overflow? Because if that's the case, the hash of the UTXO set won't match the one hardcoded in chainparams' If it's not a bad snapshot you're worried about, then as far as I can tell the same wraparound issue would exist with a normal |
|
Correct. If we don't care about integer overflows when activating invalid snapshots, then this pull can be closed. |
|
Would it make sense to instead compute the total amount as an |
|
The following sections might be updated with supplementary metadata relevant to reviewers and maintainers. ConflictsNo conflicts as of last run. |
fa5bdc9 to
fa12d4f
Compare
|
Switched to |
shaavan
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Concept ACK
This PR allows preventing integer overflow of coin_stats.total_amount while activating the snapshot.
The following points explain the PR in greater detail:
- The function
AdditionOverflowhas been moved from src/test/fuzz/util.h to a new file src/util/overflow.h. The dependencies of other files are updated accordingly. - Unit tests are added for this function, which tests on various edge cases in the case of both signed and unsigned elements.
- The
AdditionOverflowfunction is used in thecoinstats::ApplyStatsfunction to prevent the risk of an overflow of CAmount. In case if there might be an integer overflow, thetotal_amountvar is set tonullopt.
Though I have not rigorously tested this PR yet, I think the code is logically coherent.
I have just one doubt I would like to point out.
In src/test/util_tests.cpp file:
From the line BOOST_CHECK(TestAddMatrix<signed>()); I inferred that this function was made to be used with signed integers. If I am correct, then there is one logical error:
assert(TestAdd(mini, mini));
This might not always be true.
For example:
- mini = 2; mini + mini = 4 > 2 (in range) TestAdd result == true
- mini = -2; mini + mini = -4 < -2 (out of range) TestAdd result == false
fa29302 to
faff961
Compare
MINI is a compile time constant (just force pushed to rename it from mini). It allows for the test checking for underflow to be less verbose. Checking for underflow is only needed when adding signed integers. Adding two unsigned integers can only overflow. |
faff961 to
fa13888
Compare
|
Seems like the number is useful for human verification. We should probably log it or tell advanced users somewhere. Maybe instead, abort activation of snapshots that exceed |
The amounts are already covered by the hash, which is obviously trusted and verified. Thus, it will abort activation. Starting to check random consensus rules on the snapshot is going to be an open ended issue (why not check that there are no unspendable scriptPubKeys in the snapshot, ...) that doesn't give any benefit. |
shaavan
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Checking for underflow is only needed when adding signed integers. Adding two unsigned integers can only overflow.
Makes sense to me now. Since TestAddMatrix() is being used only for signed integer. The minimum possible value ( = MINI) must be < 0. In that case the assertion condition assert(TestAdd(MINI, MINI)); will never fail.
crACK fa13888199cdae682aa58b68c08d9856dbd20477
fa13888 to
fa4a86e
Compare
shaavan
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reACK fa4a86e466ed4983235307d31fbe1ef8b28829d6
Changes since my last review:
- Added a new function CheckedAdd (in overflow.h), which returns nullopt if there is an addition overflow (or underflow) and otherwise returns the sum.
- TestAdd function (in util_tests.cpp) has been removed, and its usage is replaced with CheckedAdd.
- Finally, CheckedAdd is used to simplify added code in the coinstats.cpp file.
fa4a86e to
fa72733
Compare
shaavan
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
reACK fa72733b12eac2fa038afb75c9463570b48ea34b
Changes since my last review:
- Rebased the branch on the current master.
vasild
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Concept ACK fa72733b12eac2fa038afb75c9463570b48ea34b
fa72733 to
fa996c5
Compare
|
Addressed test nits in force push. Should be trivial to re-ACK with: |
shaavan
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
vasild
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ACK fa996c5
…hen activating snapshot fa996c5 refactor: Avoid integer overflow in ApplyStats when activating snapshot (MarcoFalke) fac0188 Move AdditionOverflow to util, Add CheckedAdd with unit tests (MarcoFalke) fa526d8 Add dev doc to CCoinsStats::m_hash_type and make it const (MarcoFalke) faff051 style: Remove unused whitespace (MarcoFalke) Pull request description: A snapshot contains the utxo set, including the out value. To activate the snapshot, the hash needs to be calculated. As a side-effect, the total amount in the snapshot is calculated (as the sum of all out values), but never used. Instead of running into an integer overflow in an unused result, don't calculate the result in the first place. Other code paths (using the active utxo set) can not run into an integer overflow, since the active utxo set is valid. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=39716 ACKs for top commit: shaavan: reACK fa996c5 vasild: ACK fa996c5 Tree-SHA512: 4f207f634841f6f634fd02ae1e5907e343fd767524fd0e8149aa99fa9a1834fe50167d14874834d45236e9c325d567925f28129bacb7d80be29cf22277a16a14
A snapshot contains the utxo set, including the out value. To activate the snapshot, the hash needs to be calculated. As a side-effect, the total amount in the snapshot is calculated (as the sum of all out values), but never used. Instead of running into an integer overflow in an unused result, don't calculate the result in the first place.
Other code paths (using the active utxo set) can not run into an integer overflow, since the active utxo set is valid.
Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=39716