@@ -189,4 +189,42 @@ BOOST_AUTO_TEST_CASE(cnode_simple_test)
189
189
BOOST_CHECK (pnode2->fFeeler == false );
190
190
}
191
191
192
+ // prior to PR #14728, this test triggers an undefined behavior
193
+ BOOST_AUTO_TEST_CASE (ipv4_peer_with_ipv6_addrMe_test)
194
+ {
195
+ // set up local addresses; all that's necessary to reproduce the bug is
196
+ // that a normal IPv4 address is among the entries, but if this address is
197
+ // !IsRoutable the undefined behavior is easier to trigger deterministically
198
+ {
199
+ LOCK (cs_mapLocalHost);
200
+ in_addr ipv4AddrLocal;
201
+ ipv4AddrLocal.s_addr = 0x0100007f ;
202
+ CNetAddr addr = CNetAddr (ipv4AddrLocal);
203
+ LocalServiceInfo lsi;
204
+ lsi.nScore = 23 ;
205
+ lsi.nPort = 42 ;
206
+ mapLocalHost[addr] = lsi;
207
+ }
208
+
209
+ // create a peer with an IPv4 address
210
+ in_addr ipv4AddrPeer;
211
+ ipv4AddrPeer.s_addr = 0xa0b0c001 ;
212
+ CAddress addr = CAddress (CService (ipv4AddrPeer, 7777 ), NODE_NETWORK);
213
+ std::unique_ptr<CNode> pnode = MakeUnique<CNode>(0 , NODE_NETWORK, 0 , INVALID_SOCKET, addr, 0 , 0 , CAddress{}, std::string{}, false );
214
+ pnode->fSuccessfullyConnected .store (true );
215
+
216
+ // the peer claims to be reaching us via IPv6
217
+ in6_addr ipv6AddrLocal;
218
+ memset (ipv6AddrLocal.s6_addr , 0 , 16 );
219
+ ipv6AddrLocal.s6_addr [0 ] = 0xcc ;
220
+ CAddress addrLocal = CAddress (CService (ipv6AddrLocal, 7777 ), NODE_NETWORK);
221
+ pnode->SetAddrLocal (addrLocal);
222
+
223
+ // before patch, this causes undefined behavior detectable with clang's -fsanitize=memory
224
+ AdvertiseLocal (&*pnode);
225
+
226
+ // suppress no-checks-run warning; if this test fails, it's by triggering a sanitizer
227
+ BOOST_CHECK (1 );
228
+ }
229
+
192
230
BOOST_AUTO_TEST_SUITE_END ()
0 commit comments