mirror of
https://github.com/dashpay/dash.git
synced 2024-12-25 03:52:49 +01:00
Merge #18515: test: add BIP37 remote crash bug [CVE-2013-5700] test to p2p_filter.py
0ed2d8e07d3806d78d03a77d2153f22f9d733a07 test: add BIP37 remote crash bug [CVE-2013-5700] test to p2p_filter.py (Sebastian Falbesoner) Pull request description: Integrates the missing message type `filteradd` to the test framework and checks that the BIP37 implementation is not vulnerable to the "remote crash bug" [CVE-2013-5700](https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2013-5700) anymore. Prior to v.0.8.4, it was possible to trigger a division-by-zero error on the following line in the function `CBloomFilter::Hash()`:f0d6487e29/src/bloom.cpp (L45)
By setting a zero-length filter via `filterload`, `vData.size()` is 0, so the modulo operation above, called on any .insert() or .contains() operation then crashed the node. The test uses the approach of just sending an arbitrary `filteradd` message after, which calls `CBloomFilter::insert()` (and in turn `CBloomFilter::Hash()`) on the node. The vulnerability was fixed by commit37c6389c5a
(an intentional covert fix, [according to gmaxwell](https://github.com/bitcoin/bitcoin/issues/18483#issuecomment-608224095)), which introduced flags `isEmpty`/`isFull` that wouldn't call the `Hash()` member function if `isFull` is true (set to true by default constructor). To validate that the test fails if the implementation is vulnerable, one can simply set the flags to false in the member function `UpdateEmptyFull()` (that is called after a filter received via `filterload` is constructed), which activates the vulnerable code path calling `Hash` in any case on adding or testing for data in the filter: ```diff diff --git a/src/bloom.cpp b/src/bloom.cpp index bd6069b..ef294a3 100644 --- a/src/bloom.cpp +++ b/src/bloom.cpp @@ -199,8 +199,8 @@ void CBloomFilter::UpdateEmptyFull() full &= vData[i] == 0xff; empty &= vData[i] == 0; } - isFull = full; - isEmpty = empty; + isFull = false; + isEmpty = false; } ``` Resulting in: ``` $ ./p2p_filter.py [...] 2020-04-03T14:38:59.593000Z TestFramework (INFO): Check that division-by-zero remote crash bug [CVE-2013-5700] is fixed 2020-04-03T14:38:59.695000Z TestFramework (ERROR): Assertion failed [...] [... some exceptions following ...] ``` ACKs for top commit: naumenkogs: utACK 0ed2d8e07d3806d78d03a77d2153f22f9d733a07 Tree-SHA512: 02d0253d13eab70c4bd007b0750c56a5a92d05d419d53033523eeb3ed80318bc95196ab90f7745ea3ac9ebae7caee3adbf2a055a40a4124e0915226e49018fe8
This commit is contained in:
parent
ff89f705c0
commit
11eefa21d4
@ -11,6 +11,7 @@ from test_framework.messages import (
|
||||
MSG_FILTERED_BLOCK,
|
||||
msg_getdata,
|
||||
msg_filterload,
|
||||
msg_filteradd,
|
||||
msg_filterclear,
|
||||
)
|
||||
from test_framework.mininode import P2PInterface
|
||||
@ -97,6 +98,10 @@ class FilterTest(BitcoinTestFramework):
|
||||
txid = self.nodes[0].sendtoaddress(self.nodes[0].getnewaddress(), 7)
|
||||
filter_node.wait_for_tx(txid)
|
||||
|
||||
self.log.info("Check that division-by-zero remote crash bug [CVE-2013-5700] is fixed")
|
||||
filter_node.send_and_ping(msg_filterload(data=b'', nHashFuncs=1))
|
||||
filter_node.send_and_ping(msg_filteradd(data=b'letstrytocrashthisnode'))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
FilterTest().main()
|
||||
|
@ -1880,6 +1880,25 @@ class msg_filterload:
|
||||
self.data, self.nHashFuncs, self.nTweak, self.nFlags)
|
||||
|
||||
|
||||
class msg_filteradd:
|
||||
__slots__ = ("data")
|
||||
command = b"filteradd"
|
||||
|
||||
def __init__(self, data):
|
||||
self.data = data
|
||||
|
||||
def deserialize(self, f):
|
||||
self.data = deser_string(f)
|
||||
|
||||
def serialize(self):
|
||||
r = b""
|
||||
r += ser_string(self.data)
|
||||
return r
|
||||
|
||||
def __repr__(self):
|
||||
return "msg_filteradd(data={})".format(self.data)
|
||||
|
||||
|
||||
class msg_filterclear:
|
||||
__slots__ = ()
|
||||
command = b"filterclear"
|
||||
|
@ -38,6 +38,7 @@ from test_framework.messages import (
|
||||
msg_cfilter,
|
||||
msg_clsig,
|
||||
msg_cmpctblock,
|
||||
msg_filteradd,
|
||||
msg_filterclear,
|
||||
msg_filterload,
|
||||
msg_getaddr,
|
||||
@ -87,6 +88,7 @@ MESSAGEMAP = {
|
||||
b"cfheaders": msg_cfheaders,
|
||||
b"cfilter": msg_cfilter,
|
||||
b"cmpctblock": msg_cmpctblock,
|
||||
b"filteradd": msg_filteradd,
|
||||
b"filterclear": msg_filterclear,
|
||||
b"filterload": msg_filterload,
|
||||
b"getaddr": msg_getaddr,
|
||||
@ -394,6 +396,7 @@ class P2PInterface(P2PConnection):
|
||||
def on_cfilter(self, message): pass
|
||||
def on_cmpctblock(self, message): pass
|
||||
def on_feefilter(self, message): pass
|
||||
def on_filteradd(self, message): pass
|
||||
def on_filterclear(self, message): pass
|
||||
def on_filterload(self, message): pass
|
||||
def on_getaddr(self, message): pass
|
||||
|
Loading…
Reference in New Issue
Block a user