-
Notifications
You must be signed in to change notification settings - Fork 37.8k
net: remove is{Empty,Full} flags from CBloomFilter, clarify CVE fix #18806
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
net: remove is{Empty,Full} flags from CBloomFilter, clarify CVE fix #18806
Conversation
Concept and code review ACK 1ad8ea2 |
ACK 1ad8ea2 |
Concept ACK |
We'll cover this in review club next Wednesday: https://bitcoincore.reviews/18806.html |
utACK 1ad8ea2 |
Code review ACK 1ad8ea2 Thanks for clarifying this code! |
ACK 1ad8ea2 Reviewed and verified tests pass (including p2p_filter functional test which exercises this behavior). |
Unit tests and functional tests passing (including p2p_filter). Question: |
That is the covert part of the fix (together with a misleading commit message and merge process). It made it harder to understand that there was a vulnerability so that attackers don't find it and use it before most of the network has updated to a version that includes the fix. Once that is the case the vulnerability is made public. This post about a more recent vulnerability should give you more insight into the process: https://bitcoincore.org/en/2019/11/08/CVE-2017-18350/ |
utACK 1ad8ea2 |
ACK 1ad8ea2 reviewed changes, built and ran tests. Ran functional test p2p_filter which includes test for CVE-2013-5700 fix:
|
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.
Feedback from nehan and others during the PR review club was to consider adding an assert()
in the Hash()
method to make sure any caller is informed that a vData.empty()
check has been done to make sure vData.size()
is not 0.
@eriknylund an assertion failure is not much different than division by zero - both would terminate the program. |
@vasild Division by zero is not guaranteed to terminate the program :) |
utACK 1ad8ea2 Concept ACK adding the assert, to document the expectations. |
I'm neutral on the idea of adding an assert to |
I see. Would a simple comment be better suited in this case? |
Just a comment/assertion on |
All three test suites passed here. |
…er, clarify CVE fix 1ad8ea2 net: remove is{Empty,Full} flags from CBloomFilter, clarify CVE fix (Sebastian Falbesoner) Pull request description: The BIP37 bloom filter class `CBloomFilter` contains two flags `isEmpty`/`isFull` together with an update method with the purpose to, according to the comments, "avoid wasting cpu", i.e. the mechanism should serve as an optimization for the trivial cases of empty (all bits zero) or full (all bits one) filters. However, the real reason of adding those flags (introduced with commit bitcoin@37c6389 by gmaxwell) was a _covert fix_ of [CVE-2013-5700](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-5700), a vulnerability that allowed a divide-by-zero remote node crash. According to gmaxwell himself (bitcoin#9060 (comment)): > the IsEmpty/IsFull optimizations were largely a pretextual optimization intended to make unexploitable a remote crash vulnerability (integer division by zero) that existed in the original bloom filtering code without disclosing it. I'm doubtful that they are all that useful. :) For more information on how to trigger this crash, see PR bitcoin#18515 which contains a detailled description and a regression test. It has also been discussed on a [recent PR club meeting on fuzzing](https://bitcoincore.reviews/18521.html). The covert fix code already led to issues and PR based on the wrong assumption that the flags are there for optimization reasons (see bitcoin#16886 and bitcoin#16922). This PR gets rid of the flags and the update method and just focuses on the CVE fix itself, i.e. it can be seen as a revert of the covert fix commit modulo the actual fix. ACKs for top commit: meshcollider: utACK 1ad8ea2 laanwj: Concept and code review ACK 1ad8ea2 jkczyz: ACK 1ad8ea2 MarcoFalke: ACK 1ad8ea2 fjahr: Code review ACK 1ad8ea2 Tree-SHA512: 29f7ff9faece0285e11e16c024851f5bcb772dec64118ccc3f9067ec256267ec8e1b1e3105c7de2a72fd122c3b085e8fc840ab8f4e49813f1cc7a444df1867f7
Summary: ``` The BIP37 bloom filter class CBloomFilter contains two flags isEmpty/isFull together with an update method with the purpose to, according to the comments, "avoid wasting cpu", i.e. the mechanism should serve as an optimization for the trivial cases of empty (all bits zero) or full (all bits one) filters. However, the real reason of adding those flags (introduced with commit 37c6389 by gmaxwell) was a covert fix of CVE-2013-5700, a vulnerability that allowed a divide-by-zero remote node crash. According to gmaxwell himself (#9060 (comment)): the IsEmpty/IsFull optimizations were largely a pretextual optimization intended to make unexploitable a remote crash vulnerability (integer division by zero) that existed in the original bloom filtering code without disclosing it. I'm doubtful that they are all that useful. :) For more information on how to trigger this crash, see PR #18515 which contains a detailled description and a regression test. It has also been discussed on a recent PR club meeting on fuzzing. The covert fix code already led to issues and PR based on the wrong assumption that the flags are there for optimization reasons (see #16886 and #16922). This PR gets rid of the flags and the update method and just focuses on the CVE fix itself, i.e. it can be seen as a revert of the covert fix commit modulo the actual fix. ``` Backport of core [[bitcoin/bitcoin#18806 | PR18806]]. Test Plan: ninja all check-all ninja bitcoin-fuzzers ./src/test/fuzz/bloom_filter <path_to_corpus> Reviewers: #bitcoin_abc, PiRK Reviewed By: #bitcoin_abc, PiRK Differential Revision: https://reviews.bitcoinabc.org/D9051
Backport bloom filter improvements Cherry-picked from the following upstream PRs: - bitcoin/bitcoin#7113 - bitcoin/bitcoin#7818 - Only the second commit (to resolve conflicts). - bitcoin/bitcoin#7934 - bitcoin/bitcoin#8655 - Partial backport to help resolve conflicts. - bitcoin/bitcoin#9060 - bitcoin/bitcoin#9223 - bitcoin/bitcoin#9644 - Partial backport to help resolve conflicts. - bitcoin/bitcoin#9916 - bitcoin/bitcoin#9750 - bitcoin/bitcoin#13176 - bitcoin/bitcoin#13948 - bitcoin/bitcoin#16073 - bitcoin/bitcoin#18670 - bitcoin/bitcoin#18806 - Reveals upstream's covert fix for CVE-2013-5700. - bitcoin/bitcoin#19968
Backport bloom filter improvements Cherry-picked from the following upstream PRs: - bitcoin/bitcoin#7113 - bitcoin/bitcoin#7818 - Only the second commit (to resolve conflicts). - bitcoin/bitcoin#7934 - bitcoin/bitcoin#8655 - Partial backport to help resolve conflicts. - bitcoin/bitcoin#9060 - bitcoin/bitcoin#9223 - bitcoin/bitcoin#9644 - Partial backport to help resolve conflicts. - bitcoin/bitcoin#9916 - bitcoin/bitcoin#9750 - bitcoin/bitcoin#13176 - bitcoin/bitcoin#13948 - bitcoin/bitcoin#16073 - bitcoin/bitcoin#18670 - bitcoin/bitcoin#18806 - Reveals upstream's covert fix for CVE-2013-5700. - bitcoin/bitcoin#19968
The BIP37 bloom filter class
CBloomFilter
contains two flagsisEmpty
/isFull
together with an update method with the purpose to, according to the comments, "avoid wasting cpu", i.e. the mechanism should serve as an optimization for the trivial cases of empty (all bits zero) or full (all bits one) filters.However, the real reason of adding those flags (introduced with commit 37c6389 by gmaxwell) was a covert fix of CVE-2013-5700, a vulnerability that allowed a divide-by-zero remote node crash.
According to gmaxwell himself (#9060 (comment)):
For more information on how to trigger this crash, see PR #18515 which contains a detailled description and a regression test. It has also been discussed on a recent PR club meeting on fuzzing.
The covert fix code already led to issues and PR based on the wrong assumption that the flags are there for optimization reasons (see #16886 and #16922). This PR gets rid of the flags and the update method and just focuses on the CVE fix itself, i.e. it can be seen as a revert of the covert fix commit modulo the actual fix.