bitcoin: fuzz: banman, Assertion `banmap == banmap_read' failed

fabed982ad9143cddaca8346f6b4c243dd84e0c4 re-enabled the assert assert(banmap == banmap_read) in banman:

ban_man.DumpBanlist();
SetMockTime(ConsumeTime(fuzzed_data_provider));
banmap_t banmap;
ban_man.GetBanned(banmap);
BanMan ban_man_read{banlist_file, /* client_interface */ nullptr, /* default_ban_time */ 0};
banmap_t banmap_read;
ban_man_read.GetBanned(banmap_read);
assert(banmap == banmap_read);

However, my server crashed because of it. Debugging it I could realize the problem is the function LookupSubnet.

During the execution that caused the crash, the banman has been filled with the following subnets:

2e:6f6e:696f:6ef3:a080:b18d:5d5d:5d00%2038004089/121
191:b491:7979:7979:7979:7979:79ff:ff80%2037980897/121
207:fc26:b9ce:7aae:798b:5f2d:1d39:4380%2038004089/121
676:c962:7962:b787:b392:fed8:7058:c500%2038004089/121
...

After dumping it (DumpBanlist), we initialize a BanMan reading same file:

BanMan ban_man_read{banlist_file, /* client_interface */ nullptr, /* default_ban_time */ 0};
banmap_t banmap_read;
ban_man_read.GetBanned(banmap_read);

However, when we initialize a BanMan it will - at some point - call BanMapFromJson.

Taking a look at BanMapFromJson, I noticed we have:

if (!LookupSubNet(subnet_str, subnet)) {
    LogPrintf("Dropping entry with unparseable address or subnet (%s) from ban list\n", subnet_str);
    continue;
}

Calling LookupSubNet, for example, with 2e:6f6e:696f:6ef3:a080:b18d:5d5d:5d00%2038004089/121, will return true, but the subnet will be 2e:6f6e:696f:6ef3:a080:b18d:5d5d:5d00%31097 making the assertion assert(banmap == banmap_read) to fail.


Got this with macOS Ventura 13.0.

./configure --enable-fuzz --with-sanitizers=fuzzer,address,undefined --disable-asm CC=$(brew --prefix llvm)/bin/clang CXX=$(brew --prefix llvm)/bin/clang++

Crash:

INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 3851287319
INFO: Loaded 1 modules   (1130675 inline 8-bit counters): 1130675 [0x107b6cd60, 0x107c80e13), 
INFO: Loaded 1 PC tables (1130675 PCs): 1130675 [0x107c80e18,0x108dc1948), 
src/test/fuzz/fuzz: Running 1 inputs 1 time(s) each.
Running: crash-cc17009262908f232f471481d1ad808e2bf6dc14
Assertion failed: (banmap == banmap_read), function banman_fuzz_target, file banman.cpp, line 112.
==79739== ERROR: libFuzzer: deadly signal
    #0 0x10a453ea4 in __sanitizer_print_stack_trace+0x28 (libclang_rt.asan_osx_dynamic.dylib:arm64+0x5bea4) (BuildId: 5c04277be4ee3a049b85963fe58ab4e132000000200000000100000000000b00)
    #1 0x1070bf970 in fuzzer::PrintStackTrace() FuzzerUtil.cpp:210
    #2 0x1070a3d8c in fuzzer::Fuzzer::CrashCallback() FuzzerLoop.cpp:233
    #3 0x18065c2a0 in _sigtramp+0x34 (libsystem_platform.dylib:arm64+0x42a0) (BuildId: 781896702f47332c9a59a210157aa97b32000000200000000100000000000d00)
    #4 0xfa7f80018062dce8  (<unknown module>)
    #5 0x51270001805672c4  (<unknown module>)
    #6 0x614a00018056661c  (<unknown module>)
    #7 0x382f000104c37c88  (<unknown module>)
    #8 0x1052468f8 in LLVMFuzzerTestOneInput fuzz.cpp:169
    #9 0x1070a51c8 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) FuzzerLoop.cpp:617
    #10 0x107091590 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) FuzzerDriver.cpp:324
    #11 0x1070967c4 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) FuzzerDriver.cpp:860
    #12 0x1070c0bc0 in main FuzzerMain.cpp:20
    #13 0x180303e4c  (<unknown module>)
    #14 0x7d03fffffffffffc  (<unknown module>)

NOTE: libFuzzer has rudimentary signal handlers.
      Combine libFuzzer with AddressSanitizer or similar for better crash reports.
SUMMARY: libFuzzer: deadly signal

Seed:

X3J1bmViYX39GgAAAAAAAAD///8AACsAXAAAAFx00UUXXXQBFRUVFRUVFRUVFRVvLwB/AAAAgAABAAABAQcAAACRtJGdEZGRQAAAAMQgf38AQAqRkf/w/6cCAZG0kXl5eXl5eXl5ef//////////eXl5eXl5eXl5eXl5eXl5jMCDHsFtvdtVxH7U1agiqUM6FTiq9Tg1OfCMddTHrRhzOQ0wCFHRVS3D7kqAmf4ii4FzNYkn9XcN8ubYNitv6cgN9E1kKPbQJOCC2dYrPDwDDQHZQeqOD7K+uD8GdslieWK3h7OS/thwWMUdw+KmgryaSZvunotnNKkz/uq98HjtQrUH/LUmUeb7pTZHqTApZ3jXVmGS2Muo96HLI9g3d0EG5LHce+mRSy2jB6TFuBRAQpwjghLRiU+S75ltwhrmRUXBfa4kpmjq2FrBYiVbbTYisifxMsnvPS7ix+IwpTats2ewEGQITg/MeZbhvKcZxxczHeb6ht1PrRV4/o/msCwN2d8RVC0DYh2gqj1aC06cGMXgoZw+T3ll5CH8dghESnW98W3i283GUy/3tSwPV8GLot5X/DupHLge/RQxtmgnIJhXgq/UMzTL7XK9y1oMooLSPiDhJiVmrKE95f549o1H9UZXSx1mwGCqap51HHrCSsnjiP13Wn1+WtyEUUAObNBDhcSjuHMMWY95B938zoOKTbFpyY3gzAi5Z8ujR2KmnEaKT4MKAVGQAAAAAAAAAAAAAAAAAAAAAP5W0ABJaWjFneFMmuY9koAoGVtScppmwwOw9++Ufx0dTyvFjZHkROJ6mlu0UKCvY6sTccKSugFu0/QncpR5/DBzYqTSe0OKQSMhzIN2HQEAo05OWxU9XQsTKRfg/bSB1//EXudt4jZEIyns29ZRAAAAAAAAAAB5cXFxcXFxcXFxcXFxcXFxcXl5PgAAAAAAAABwkZiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmEAAAC5vbmlvbvOggLGNXV1dDV0NAABVlEQAXRAAP11d+gj/f7+12l1VlABdEF0AROA9//////8I/38I/yZ/CP9/CP9/CP9/CP9/B/9/CHl5eXn/////////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAeXl5eQB5ecJ5eQF0eXl5eXl5eXl5eXkAgDsAAACAeXkmeXmwV3P1HqaLvq9HJCO3LQzu6Khz1/N6ndp/+0uXhvDVw6ekexeobSVOnFS7455nfwXAfGVyqxh8mvHWMdOKECKCa6HLBzj/rHbPG+HNtG/wvAIH/Ca5znqueYtfLR05Q66eoEheVZbgZSZn9xtbTUOMCPf+fwZ/3/wCs5ve9RqjRhRopnTXzm6R53SyY8OhPkjZfmHekZiP4qpCUN0rFIU8cZojTVAUZWJjT7OKXmAgZ5GWTGuyos8GKQMfmo4KCFuwt0/0+x9aKSC2z5JDTqebow5cVrdEjrozEjNXNL36tvOaLdGvcMfJ8xlUmOjI6DU+pmEn4ZUXUxUu9CnwZ8ZsjJcs0bOiVJd5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eYeHeXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5fXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5/YfYfutDeXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXkAeXl5eeEeeXl5eXl6eYATE3l5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl9eXl5eQCAOwAAAIB5eXl5eQ==

The following diff reproduces the behavior:

diff --git a/src/test/banman_tests.cpp b/src/test/banman_tests.cpp
index cebe3629d..d24f55979 100644
--- a/src/test/banman_tests.cpp
+++ b/src/test/banman_tests.cpp
@@ -20,11 +20,12 @@ BOOST_AUTO_TEST_CASE(file)
     SetMockTime(777s);
     const fs::path banlist_path{m_args.GetDataDirBase() / "banlist_test"};
     {
+        const std::string suspect_subnet{"2e:6f6e:696f:6ef3:a080:b18d:5d5d:5d00%2038004089/121"};
         const std::string entries_write{
             "{ \"banned_nets\": ["
             "  { \"version\": 1, \"ban_created\": 0, \"banned_until\": 778, \"address\": \"aaaaaaaaa\" },"
             "  { \"version\": 2, \"ban_created\": 0, \"banned_until\": 778, \"address\": \"bbbbbbbbb\" },"
-            "  { \"version\": 1, \"ban_created\": 0, \"banned_until\": 778, \"address\": \"1.0.0.0/8\" }"
+            "  { \"version\": 1, \"ban_created\": 0, \"banned_until\": 778, \"address\": \"2e:6f6e:696f:6ef3:a080:b18d:5d5d:5d00%2038004089/121\" }"
             "] }",
         };
         BOOST_REQUIRE(WriteBinaryFile(banlist_path + ".json", entries_write));
@@ -36,6 +37,11 @@ BOOST_AUTO_TEST_CASE(file)
             banmap_t entries_read;
             banman.GetBanned(entries_read);
             BOOST_CHECK_EQUAL(entries_read.size(), 1);
+
+            for (const auto& it : entries_read) {
+                CSubNet sub_net = it.first;
+                BOOST_CHECK_EQUAL(sub_net.ToString(), suspect_subnet);
+            }
         }
     }
 }
diff --git a/test/functional/rpc_setban.py b/test/functional/rpc_setban.py
index b4f3d77e5..93a19920c 100755
--- a/test/functional/rpc_setban.py
+++ b/test/functional/rpc_setban.py
@@ -25,6 +25,10 @@ class SetBanTests(BitcoinTestFramework):
         peerinfo = self.nodes[1].getpeerinfo()[0]
         assert not "noban" in peerinfo["permissions"]
 
+        subnet = "2e:6f6e:696f:6ef3:a080:b18d:5d5d:5d00%2038004089/121"
+        self.nodes[1].setban(subnet, "add")
+        assert self.is_banned(self.nodes[1], subnet)
+
         # Node 0 get banned by Node 1
         self.nodes[1].setban("127.0.0.1", "add")

About this issue

  • Original URL
  • State: closed
  • Created a year ago
  • Comments: 23 (23 by maintainers)

Commits related to this issue

Most upvoted comments

I’m able to reproduce this on an Intel MacOS Ventura

Also in the fuzz target with the input that bruno provided here: #27924 (comment) ?

$ echo "X3J1bmViYX39GgAAAAAAAAD///8AACsAXAAAAFx00UUXXXQBFRUVFRUVFRUVFRVvLwB/AAAAgAABAAABAQcAAACRtJGdEZGRQAAAAMQgf38AQAqRkf/w/6cCAZG0kXl5eXl5eXl5ef//////////eXl5eXl5eXl5eXl5eXl5jMCDHsFtvdtVxH7U1agiqUM6FTiq9Tg1OfCMddTHrRhzOQ0wCFHRVS3D7kqAmf4ii4FzNYkn9XcN8ubYNitv6cgN9E1kKPbQJOCC2dYrPDwDDQHZQeqOD7K+uD8GdslieWK3h7OS/thwWMUdw+KmgryaSZvunotnNKkz/uq98HjtQrUH/LUmUeb7pTZHqTApZ3jXVmGS2Muo96HLI9g3d0EG5LHce+mRSy2jB6TFuBRAQpwjghLRiU+S75ltwhrmRUXBfa4kpmjq2FrBYiVbbTYisifxMsnvPS7ix+IwpTats2ewEGQITg/MeZbhvKcZxxczHeb6ht1PrRV4/o/msCwN2d8RVC0DYh2gqj1aC06cGMXgoZw+T3ll5CH8dghESnW98W3i283GUy/3tSwPV8GLot5X/DupHLge/RQxtmgnIJhXgq/UMzTL7XK9y1oMooLSPiDhJiVmrKE95f549o1H9UZXSx1mwGCqap51HHrCSsnjiP13Wn1+WtyEUUAObNBDhcSjuHMMWY95B938zoOKTbFpyY3gzAi5Z8ujR2KmnEaKT4MKAVGQAAAAAAAAAAAAAAAAAAAAAP5W0ABJaWjFneFMmuY9koAoGVtScppmwwOw9++Ufx0dTyvFjZHkROJ6mlu0UKCvY6sTccKSugFu0/QncpR5/DBzYqTSe0OKQSMhzIN2HQEAo05OWxU9XQsTKRfg/bSB1//EXudt4jZEIyns29ZRAAAAAAAAAAB5cXFxcXFxcXFxcXFxcXFxcXl5PgAAAAAAAABwkZiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmEAAAC5vbmlvbvOggLGNXV1dDV0NAABVlEQAXRAAP11d+gj/f7+12l1VlABdEF0AROA9//////8I/38I/yZ/CP9/CP9/CP9/CP9/B/9/CHl5eXn/////////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAeXl5eQB5ecJ5eQF0eXl5eXl5eXl5eXkAgDsAAACAeXkmeXmwV3P1HqaLvq9HJCO3LQzu6Khz1/N6ndp/+0uXhvDVw6ekexeobSVOnFS7455nfwXAfGVyqxh8mvHWMdOKECKCa6HLBzj/rHbPG+HNtG/wvAIH/Ca5znqueYtfLR05Q66eoEheVZbgZSZn9xtbTUOMCPf+fwZ/3/wCs5ve9RqjRhRopnTXzm6R53SyY8OhPkjZfmHekZiP4qpCUN0rFIU8cZojTVAUZWJjT7OKXmAgZ5GWTGuyos8GKQMfmo4KCFuwt0/0+x9aKSC2z5JDTqebow5cVrdEjrozEjNXNL36tvOaLdGvcMfJ8xlUmOjI6DU+pmEn4ZUXUxUu9CnwZ8ZsjJcs0bOiVJd5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eYeHeXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5fXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5/YfYfutDeXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXkAeXl5eeEeeXl5eXl6eYATE3l5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl9eXl5eQCAOwAAAIB5eXl5eQ==" | base64 --decode > banman_crash.input
$ FUZZ=banman ./src/test/fuzz/fuzz banman_crash.input

I was also able to reproduce this.

fuzz(26710,0x7ff84ab44640) malloc: nano zone abandoned due to inability to reserve vm space.
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 2487386717
INFO: Loaded 1 modules   (1139295 inline 8-bit counters): 1139295 [0x103800bb8, 0x103916e17),
INFO: Loaded 1 PC tables (1139295 PCs): 1139295 [0x103916e18,0x104a79408),
./src/test/fuzz/fuzz: Running 1 inputs 1 time(s) each.
Running: banman_crash.input
Assertion failed: (banmap == banmap_read), function banman_fuzz_target, file banman.cpp, line 112.
==26710== ERROR: libFuzzer: deadly signal
    #0 0x1062e1fc5 in __sanitizer_print_stack_trace+0x35 (libclang_rt.asan_osx_dynamic.dylib:x86_64h+0xeafc5) (BuildId: ee4eaac7009837bb882d9429775389b32400000010000000000a0a0000030d00)
    #1 0x102e9a928 in fuzzer::PrintStackTrace() FuzzerUtil.cpp:210
    #2 0x102e7d793 in fuzzer::Fuzzer::CrashCallback() FuzzerLoop.cpp:233
    #3 0x7ff8074955ec in _sigtramp+0x1c (libsystem_platform.dylib:x86_64+0x35ec) (BuildId: 4ff3bd2f21673ee6a55d384703bdf1f5240000001000000000040d0000040d00)

NOTE: libFuzzer has rudimentary signal handlers.
      Combine libFuzzer with AddressSanitizer or similar for better crash reports.
SUMMARY: libFuzzer: deadly signal

I’m able to reproduce this on an Intel MacOS Ventura

Also in the fuzz target with the input that bruno provided here: https://github.com/bitcoin/bitcoin/issues/27924#issuecomment-1601001837 ?

Sorry I should have been more specific.

I haven’t tried the fuzz, will do that later and report back

Unless there is a bug, fuzz harnesses are not able to perform dns lookups.

@dergoegge, Seems we’re not doing dns lookups. What happens is thatLookupSubNet calls LookupHost with fAllowLookup=false. See:

bool LookupSubNet(const std::string& subnet_str, CSubNet& subnet_out)
{
    if (!ContainsNoNUL(subnet_str)) {
        return false;
    }

    const size_t slash_pos{subnet_str.find_last_of('/')};
    const std::string str_addr{subnet_str.substr(0, slash_pos)};
    const std::optional<CNetAddr> addr{LookupHost(str_addr, /*fAllowLookup=*/false)};

So it will call WrappedGetAddrInfo and consequently call getaddrinfo with AI_NUMERICHOST.

See:

std::vector<CNetAddr> WrappedGetAddrInfo(const std::string& name, bool allow_lookup)
{
    addrinfo ai_hint{};
    // We want a TCP port, which is a streaming socket type
    ai_hint.ai_socktype = SOCK_STREAM;
    ai_hint.ai_protocol = IPPROTO_TCP;
    // We don't care which address family (IPv4 or IPv6) is returned
    ai_hint.ai_family = AF_UNSPEC;
    // If we allow lookups of hostnames, use the AI_ADDRCONFIG flag to only
    // return addresses whose family we have an address configured for.
    //
    // If we don't allow lookups, then use the AI_NUMERICHOST flag for
    // getaddrinfo to only decode numerical network addresses and suppress
    // hostname lookups.
    ai_hint.ai_flags = allow_lookup ? AI_ADDRCONFIG : AI_NUMERICHOST;

    addrinfo* ai_res{nullptr};
    const int n_err{getaddrinfo(name.c_str(), nullptr, &ai_hint, &ai_res)};
    if (n_err != 0) {
        return {};
    }

    // Traverse the linked list starting with ai_trav.
    addrinfo* ai_trav{ai_res};
    std::vector<CNetAddr> resolved_addresses;
    while (ai_trav != nullptr) {
        if (ai_trav->ai_family == AF_INET) {
            assert(ai_trav->ai_addrlen >= sizeof(sockaddr_in));
            resolved_addresses.emplace_back(reinterpret_cast<sockaddr_in*>(ai_trav->ai_addr)->sin_addr);
        }
        if (ai_trav->ai_family == AF_INET6) {
            assert(ai_trav->ai_addrlen >= sizeof(sockaddr_in6));
            const sockaddr_in6* s6{reinterpret_cast<sockaddr_in6*>(ai_trav->ai_addr)};
            resolved_addresses.emplace_back(s6->sin6_addr, s6->sin6_scope_id);
        }
        ai_trav = ai_trav->ai_next;
    }
    freeaddrinfo(ai_res);

    return resolved_addresses;
}

I did more investigations and checked the issue is WrappedGetAddrInfo, could it be something with getaddrinfo call?

Unless there is a bug, fuzz harnesses are not able to perform dns lookups.

https://github.com/bitcoin/bitcoin/blob/0c84a0e4841f00d931aa7339e9aa8f26eb2f3a61/src/test/fuzz/fuzz.cpp#L77-L83

Sorry for not being so clear, @MarcoFalke. I added the diffs in functional tests and unit tests to validate my idea why fuzz failed.

Crash:

INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 3851287319
INFO: Loaded 1 modules   (1130675 inline 8-bit counters): 1130675 [0x107b6cd60, 0x107c80e13), 
INFO: Loaded 1 PC tables (1130675 PCs): 1130675 [0x107c80e18,0x108dc1948), 
src/test/fuzz/fuzz: Running 1 inputs 1 time(s) each.
Running: crash-cc17009262908f232f471481d1ad808e2bf6dc14
Assertion failed: (banmap == banmap_read), function banman_fuzz_target, file banman.cpp, line 112.
==79739== ERROR: libFuzzer: deadly signal
    #0 0x10a453ea4 in __sanitizer_print_stack_trace+0x28 (libclang_rt.asan_osx_dynamic.dylib:arm64+0x5bea4) (BuildId: 5c04277be4ee3a049b85963fe58ab4e132000000200000000100000000000b00)
    #1 0x1070bf970 in fuzzer::PrintStackTrace() FuzzerUtil.cpp:210
    #2 0x1070a3d8c in fuzzer::Fuzzer::CrashCallback() FuzzerLoop.cpp:233
    #3 0x18065c2a0 in _sigtramp+0x34 (libsystem_platform.dylib:arm64+0x42a0) (BuildId: 781896702f47332c9a59a210157aa97b32000000200000000100000000000d00)
    #4 0xfa7f80018062dce8  (<unknown module>)
    #5 0x51270001805672c4  (<unknown module>)
    #6 0x614a00018056661c  (<unknown module>)
    #7 0x382f000104c37c88  (<unknown module>)
    #8 0x1052468f8 in LLVMFuzzerTestOneInput fuzz.cpp:169
    #9 0x1070a51c8 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) FuzzerLoop.cpp:617
    #10 0x107091590 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) FuzzerDriver.cpp:324
    #11 0x1070967c4 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) FuzzerDriver.cpp:860
    #12 0x1070c0bc0 in main FuzzerMain.cpp:20
    #13 0x180303e4c  (<unknown module>)
    #14 0x7d03fffffffffffc  (<unknown module>)

NOTE: libFuzzer has rudimentary signal handlers.
      Combine libFuzzer with AddressSanitizer or similar for better crash reports.
SUMMARY: libFuzzer: deadly signal

Seed:

X3J1bmViYX39GgAAAAAAAAD///8AACsAXAAAAFx00UUXXXQBFRUVFRUVFRUVFRVvLwB/AAAAgAABAAABAQcAAACRtJGdEZGRQAAAAMQgf38AQAqRkf/w/6cCAZG0kXl5eXl5eXl5ef//////////eXl5eXl5eXl5eXl5eXl5jMCDHsFtvdtVxH7U1agiqUM6FTiq9Tg1OfCMddTHrRhzOQ0wCFHRVS3D7kqAmf4ii4FzNYkn9XcN8ubYNitv6cgN9E1kKPbQJOCC2dYrPDwDDQHZQeqOD7K+uD8GdslieWK3h7OS/thwWMUdw+KmgryaSZvunotnNKkz/uq98HjtQrUH/LUmUeb7pTZHqTApZ3jXVmGS2Muo96HLI9g3d0EG5LHce+mRSy2jB6TFuBRAQpwjghLRiU+S75ltwhrmRUXBfa4kpmjq2FrBYiVbbTYisifxMsnvPS7ix+IwpTats2ewEGQITg/MeZbhvKcZxxczHeb6ht1PrRV4/o/msCwN2d8RVC0DYh2gqj1aC06cGMXgoZw+T3ll5CH8dghESnW98W3i283GUy/3tSwPV8GLot5X/DupHLge/RQxtmgnIJhXgq/UMzTL7XK9y1oMooLSPiDhJiVmrKE95f549o1H9UZXSx1mwGCqap51HHrCSsnjiP13Wn1+WtyEUUAObNBDhcSjuHMMWY95B938zoOKTbFpyY3gzAi5Z8ujR2KmnEaKT4MKAVGQAAAAAAAAAAAAAAAAAAAAAP5W0ABJaWjFneFMmuY9koAoGVtScppmwwOw9++Ufx0dTyvFjZHkROJ6mlu0UKCvY6sTccKSugFu0/QncpR5/DBzYqTSe0OKQSMhzIN2HQEAo05OWxU9XQsTKRfg/bSB1//EXudt4jZEIyns29ZRAAAAAAAAAAB5cXFxcXFxcXFxcXFxcXFxcXl5PgAAAAAAAABwkZiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmJiYmEAAAC5vbmlvbvOggLGNXV1dDV0NAABVlEQAXRAAP11d+gj/f7+12l1VlABdEF0AROA9//////8I/38I/yZ/CP9/CP9/CP9/CP9/B/9/CHl5eXn/////////////////////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAeXl5eQB5ecJ5eQF0eXl5eXl5eXl5eXkAgDsAAACAeXkmeXmwV3P1HqaLvq9HJCO3LQzu6Khz1/N6ndp/+0uXhvDVw6ekexeobSVOnFS7455nfwXAfGVyqxh8mvHWMdOKECKCa6HLBzj/rHbPG+HNtG/wvAIH/Ca5znqueYtfLR05Q66eoEheVZbgZSZn9xtbTUOMCPf+fwZ/3/wCs5ve9RqjRhRopnTXzm6R53SyY8OhPkjZfmHekZiP4qpCUN0rFIU8cZojTVAUZWJjT7OKXmAgZ5GWTGuyos8GKQMfmo4KCFuwt0/0+x9aKSC2z5JDTqebow5cVrdEjrozEjNXNL36tvOaLdGvcMfJ8xlUmOjI6DU+pmEn4ZUXUxUu9CnwZ8ZsjJcs0bOiVJd5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eYeHeXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5fXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5/YfYfutDeXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXkAeXl5eeEeeXl5eXl6eYATE3l5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl5eXl9eXl5eQCAOwAAAIB5eXl5eQ==

Do you have steps to reproduce?