diff options
author | Kaz Wesley <kaz@lambdaverse.org> | 2018-11-15 12:34:46 -0800 |
---|---|---|
committer | Kaz Wesley <kaz@lambdaverse.org> | 2018-11-15 13:47:53 -0800 |
commit | 8ebbef016928811756e46b9086067d1c826797a8 (patch) | |
tree | c5678b2f6d6068c5901483a89e2a8ca63fcdb6cb /src | |
parent | e74649e95122c9c61aadf607461cf701c3953f88 (diff) |
add test demonstrating addrLocal UB
Diffstat (limited to 'src')
-rw-r--r-- | src/test/net_tests.cpp | 38 |
1 files changed, 38 insertions, 0 deletions
diff --git a/src/test/net_tests.cpp b/src/test/net_tests.cpp index 213afed730..c1ee231d8a 100644 --- a/src/test/net_tests.cpp +++ b/src/test/net_tests.cpp @@ -189,4 +189,42 @@ BOOST_AUTO_TEST_CASE(cnode_simple_test) BOOST_CHECK(pnode2->fFeeler == false); } +// prior to PR #14728, this test triggers an undefined behavior +BOOST_AUTO_TEST_CASE(ipv4_peer_with_ipv6_addrMe_test) +{ + // set up local addresses; all that's necessary to reproduce the bug is + // that a normal IPv4 address is among the entries, but if this address is + // !IsRoutable the undefined behavior is easier to trigger deterministically + { + LOCK(cs_mapLocalHost); + in_addr ipv4AddrLocal; + ipv4AddrLocal.s_addr = 0x0100007f; + CNetAddr addr = CNetAddr(ipv4AddrLocal); + LocalServiceInfo lsi; + lsi.nScore = 23; + lsi.nPort = 42; + mapLocalHost[addr] = lsi; + } + + // create a peer with an IPv4 address + in_addr ipv4AddrPeer; + ipv4AddrPeer.s_addr = 0xa0b0c001; + CAddress addr = CAddress(CService(ipv4AddrPeer, 7777), NODE_NETWORK); + std::unique_ptr<CNode> pnode = MakeUnique<CNode>(0, NODE_NETWORK, 0, INVALID_SOCKET, addr, 0, 0, CAddress{}, std::string{}, false); + pnode->fSuccessfullyConnected.store(true); + + // the peer claims to be reaching us via IPv6 + in6_addr ipv6AddrLocal; + memset(ipv6AddrLocal.s6_addr, 0, 16); + ipv6AddrLocal.s6_addr[0] = 0xcc; + CAddress addrLocal = CAddress(CService(ipv6AddrLocal, 7777), NODE_NETWORK); + pnode->SetAddrLocal(addrLocal); + + // before patch, this causes undefined behavior detectable with clang's -fsanitize=memory + AdvertiseLocal(&*pnode); + + // suppress no-checks-run warning; if this test fails, it's by triggering a sanitizer + BOOST_CHECK(1); +} + BOOST_AUTO_TEST_SUITE_END() |