scriptpubkeyman fuzz target creates Base58 too large; Fails on 32-bit (armhf, …) #34110

issue maflcko openend this issue on December 19, 2025
  1. maflcko commented at 8:12 am on December 19, 2025: member

    Decoding should not behave differently on different architectures. See also the related commit 3789215f73466606eb111714f596a2a5e9bb1933.

    However, the scriptpubkeyman fuzz target seems to create base58 strings so large that uint32_t overflows for calculations in base58.cpp.

    This is a bit hard to reproduce, because 32-bit platforms are rare and most of them don’t support running the unsigned integer overflow sanitizer. So the possible options to reproduce are:

    • Run on armhf and manually annotate the code to detect the overflow
    • Run on i386 with the integer sanitizer (possibly via podman run -it --rm --platform linux/i386 'debian:trixie')
    • Run the integer sanitizer on any 64-bit platform and manually replace type in the affected line by uint32_t

    Afterwards, the steps to reproduce are:

    0export DEBIAN_FRONTEND=noninteractive && apt update && apt install curl wget htop git vim ccache -y && git clone https://github.com/bitcoin/bitcoin.git  --depth=1 ./b-c && cd b-c && apt install build-essential cmake pkg-config  python3-zmq libzmq3-dev libevent-dev libboost-dev libsqlite3-dev  systemtap-sdt-dev  libcapnp-dev capnproto  libqrencode-dev qt6-tools-dev qt6-l10n-tools qt6-base-dev  clang llvm libc++-dev libc++abi-dev   -y
    1
    2cmake -B ./bld-cmake -DCMAKE_BUILD_TYPE=Debug -DCMAKE_C_COMPILER='clang' -DCMAKE_CXX_COMPILER='clang++' -DSANITIZERS=undefined,integer,float-divide-by-zero --preset=dev-mode
    3
    4cmake --build ./bld-cmake --parallel  $(nproc)
    5
    6curl -fLO 'https://github.com/bitcoin-core/qa-assets/raw/b5ad78e070e4cf36beb415d7b490d948d70ba73f/fuzz_corpora/scriptpubkeyman/1cf91e0c6bfff9dafcd4db5b0ba36b1e906f4cf5'
    7
    8UBSAN_OPTIONS="suppressions=$(pwd)/test/sanitizer_suppressions/ubsan:print_stacktrace=1:halt_on_error=1:report_error_type=1" FUZZ=scriptpubkeyman ./bld-cmake/bin/fuzz ./1cf91e0c6bfff9dafcd4db5b0ba36b1e906f4cf5
    

    The output will be something like:

     0/b-c/src/base58.cpp:54:28: runtime error: unsigned integer overflow: 8744655 * 733 cannot be represented in type 'size_t' (aka 'unsigned int')
     1    [#0](/bitcoin-bitcoin/0/) 0x5985f849 in DecodeBase58(char const*, std::vector<unsigned char, std::allocator<unsigned char>>&, int) /b-c/bld-cmake/src/./base58.cpp:54:28
     2    [#1](/bitcoin-bitcoin/1/) 0x59860a8b in DecodeBase58Check(char const*, std::vector<unsigned char, std::allocator<unsigned char>>&, int) /b-c/bld-cmake/src/./base58.cpp:148:10
     3    [#2](/bitcoin-bitcoin/2/) 0x5986093b in DecodeBase58Check(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::vector<unsigned char, std::allocator<unsigned char>>&, int) /b-c/bld-cmake/src/./base58.cpp:168:12
     4    [#3](/bitcoin-bitcoin/3/) 0x599c4fc8 in DecodeSecret(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&) /b-c/bld-cmake/src/./key_io.cpp:217:9
     5    [#4](/bitcoin-bitcoin/4/) 0x59b05478 in (anonymous namespace)::ParsePubkeyInner(unsigned int, std::span<char const, 4294967295u> const&, (anonymous namespace)::ParseScriptContext, FlatSigningProvider&, bool&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&) /b-c/bld-cmake/src/./script/descriptor.cpp:1789:20
     6    [#5](/bitcoin-bitcoin/5/) 0x59af4256 in (anonymous namespace)::ParsePubkey(unsigned int&, std::span<char const, 4294967295u> const&, (anonymous namespace)::ParseScriptContext, FlatSigningProvider&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&) /b-c/bld-cmake/src/./script/descriptor.cpp:1978:16
     7    [#6](/bitcoin-bitcoin/6/) 0x59adc3af in (anonymous namespace)::ParseScript(unsigned int&, std::span<char const, 4294967295u>&, (anonymous namespace)::ParseScriptContext, FlatSigningProvider&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&) /b-c/bld-cmake/src/./script/descriptor.cpp:2148:24
     8    [#7](/bitcoin-bitcoin/7/) 0x59adbc65 in Parse(std::basic_string_view<char, std::char_traits<char>>, FlatSigningProvider&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, bool) /b-c/bld-cmake/src/./script/descriptor.cpp:2751:16
     9    [#8](/bitcoin-bitcoin/8/) 0x597ad5de in wallet::(anonymous namespace)::CreateWalletDescriptor(FuzzedDataProvider&) /b-c/bld-cmake/src/test/fuzz/./wallet/test/fuzz/scriptpubkeyman.cpp:73:61
    10    [#9](/bitcoin-bitcoin/9/) 0x597ac489 in wallet::(anonymous namespace)::scriptpubkeyman_fuzz_target(std::span<unsigned char const, 4294967295u>) /b-c/bld-cmake/src/test/fuzz/./wallet/test/fuzz/scriptpubkeyman.cpp:104:22
    11    [#10](/bitcoin-bitcoin/10/) 0x58950a8e in void std::__invoke_impl<void, void (*&)(std::span<unsigned char const, 4294967295u>), std::span<unsigned char const, 4294967295u>>(std::__invoke_other, void (*&)(std::span<unsigned char const, 4294967295u>), std::span<unsigned char const, 4294967295u>&&) /usr/lib/gcc/i686-linux-gnu/14/../../../../include/c++/14/bits/invoke.h:61:14
    12    [#11](/bitcoin-bitcoin/11/) 0x589508eb in std::enable_if<is_invocable_r_v<void, void (*&)(std::span<unsigned char const, 4294967295u>), std::span<unsigned char const, 4294967295u>>, void>::type std::__invoke_r<void, void (*&)(std::span<unsigned char const, 4294967295u>), std::span<unsigned char const, 4294967295u>>(void (*&)(std::span<unsigned char const, 4294967295u>), std::span<unsigned char const, 4294967295u>&&) /usr/lib/gcc/i686-linux-gnu/14/../../../../include/c++/14/bits/invoke.h:111:2
    13    [#12](/bitcoin-bitcoin/12/) 0x5895044b in std::_Function_handler<void (std::span<unsigned char const, 4294967295u>), void (*)(std::span<unsigned char const, 4294967295u>)>::_M_invoke(std::_Any_data const&, std::span<unsigned char const, 4294967295u>&&) /usr/lib/gcc/i686-linux-gnu/14/../../../../include/c++/14/bits/std_function.h:290:9
    14    [#13](/bitcoin-bitcoin/13/) 0x5982ac95 in std::function<void (std::span<unsigned char const, 4294967295u>)>::operator()(std::span<unsigned char const, 4294967295u>) const /usr/lib/gcc/i686-linux-gnu/14/../../../../include/c++/14/bits/std_function.h:591:9
    15    [#14](/bitcoin-bitcoin/14/) 0x5981f0da in test_one_input(std::span<unsigned char const, 4294967295u>) /b-c/bld-cmake/src/test/fuzz/util/./test/fuzz/fuzz.cpp:88:5
    16    [#15](/bitcoin-bitcoin/15/) 0x59821b80 in main /b-c/bld-cmake/src/test/fuzz/util/./test/fuzz/fuzz.cpp:271:13
    17    [#16](/bitcoin-bitcoin/16/) 0xf75a8cc2  (/lib/i386-linux-gnu/libc.so.6+0x24cc2) (BuildId: 2dc5f2945fad35c1b07d1a5a32520b3c41afaa75)
    18    [#17](/bitcoin-bitcoin/17/) 0xf75a8d87 in __libc_start_main (/lib/i386-linux-gnu/libc.so.6+0x24d87) (BuildId: 2dc5f2945fad35c1b07d1a5a32520b3c41afaa75)
    19    [#18](/bitcoin-bitcoin/18/) 0x58917db6 in _start (/b-c/bld-cmake/bin/fuzz+0x235ddb6) (BuildId: 7d8d83a77923f14e99c0de64acbc5f5bfc2cce9b)
    20
    21SUMMARY: UndefinedBehaviorSanitizer: unsigned-integer-overflow /b-c/src/base58.cpp:54:28 
    

    Obviously, it would be trivial to fix this by using the same type on 64-bit and 32-bit:

     0    refactor: Use uint64_t over size_t for multiplications in DecodeBase58
     1
     2diff --git a/src/base58.cpp b/src/base58.cpp
     3index 19a5bd3e55..5364b8276b 100644
     4--- a/src/base58.cpp
     5+++ b/src/base58.cpp
     6@@ -51,7 +51,7 @@ static const int8_t mapBase58[256] = {
     7         psz++;
     8     }
     9     // Allocate enough space in big-endian base256 representation.
    10-    int size = strlen(psz) * 733 /1000 + 1; // log(58) / log(256), rounded up.
    11+    int size(uint64_t{std::strlen(psz)} * 733 / 1000 + 1); // log(58) / log(256), rounded up.
    12     std::vector<unsigned char> b256(size);
    13     // Process the characters.
    14     static_assert(std::size(mapBase58) == 256, "mapBase58.size() should be 256"); // guarantee not out of range
    

    However, this seems like the wrong fix. A string of size 8744655 seems a bit large and should probably be rejected by the wallet code (if applicable), or by the fuzz target, if the condition is unreachable in a production wallet.

  2. maflcko added the label Wallet on Dec 19, 2025
  3. brunoerg commented at 4:59 pm on December 26, 2025: contributor
    The scriptpubkeyman target creates a wallet based on a descriptor from the input. So it basically creates random descriptors which is leading to create this specific case where it’s a pk() fragment with a super large content into it. Besides this overflow issue I think these large descriptors are unproductive and makes the target slower, so could we reject large descriptors in the fuzz target?
  4. maflcko commented at 5:15 pm on December 26, 2025: member

    could we reject large descriptors in the fuzz target?

    Yeah, that makes sense. I wonder if there is ever a use-case to expand any immediately following %ij%kl in the GetDescriptor helper. (Assuming this is what happens here). If no use-case exists, a requirement could be added to have any character in-between.

    A hacky one-line diff to achieve that could be:

     0diff --git a/src/test/fuzz/util/descriptor.cpp b/src/test/fuzz/util/descriptor.cpp
     1index 9e52e990a2..debd6a43fd 100644
     2--- a/src/test/fuzz/util/descriptor.cpp
     3+++ b/src/test/fuzz/util/descriptor.cpp
     4@@ -62,7 +62,7 @@ std::optional<std::string> MockedDescriptorConverter::GetDescriptor(std::string_
     5             if (i + 3 >= mocked_desc.size()) return {};
     6             if (const auto idx = IdxFromHex(mocked_desc.substr(i + 1, 2))) {
     7                 desc += keys_str[*idx];
     8-                i += 3;
     9+                i += 4;
    10             } else {
    11                 return {};
    12             }
    

    I haven’t tried that, and if it works, it will need an explanatory comment.

  5. brunoerg commented at 3:30 pm on December 29, 2025: contributor

    I wonder if there is ever a use-case to expand any immediately following %ij%kl in the GetDescriptor helper. (Assuming this is what happens here). If no use-case exists, a requirement could be added to have any character in-between.

    I think there is no use-case for expanding it, keys typically need to be separated by something so your suggestion makes sense. Perhaps a comment that explains it could be:

     0diff --git a/src/test/fuzz/util/descriptor.cpp b/src/test/fuzz/util/descriptor.cpp
     1index 9e52e990a2..7c5e43206a 100644
     2--- a/src/test/fuzz/util/descriptor.cpp
     3+++ b/src/test/fuzz/util/descriptor.cpp
     4@@ -62,7 +62,8 @@ std::optional<std::string> MockedDescriptorConverter::GetDescriptor(std::string_
     5             if (i + 3 >= mocked_desc.size()) return {};
     6             if (const auto idx = IdxFromHex(mocked_desc.substr(i + 1, 2))) {
     7                 desc += keys_str[*idx];
     8-                i += 3;
     9+               // Consume %ij (3 chars) + 1 separator. Prevents invalid consecutive placeholders like %00%01
    10+                i += 4;
    11             } else {
    
  6. maflcko commented at 12:08 pm on December 30, 2025: member
    I guess my above diff may not fully fix long strings and requiring a separator like , or ) after any %ij may also be needed.
  7. brunoerg commented at 12:34 pm on December 30, 2025: contributor
    I still think we should reject long strings in the target anyway. I think it’s maybe the only way to avoid these large descriptors that are improductive and make the target slower.
  8. maflcko commented at 12:59 pm on December 30, 2025: member

    The rpc target has base58 strings capped at max_base58_bytes_length{64}. Not sure if we want to limit all descriptors to this size.

    I think to check that each inner fragment string is less than maximum meaningful byte length, could make sense.

  9. maflcko commented at 11:24 am on January 8, 2026: member

    I think to check that each inner fragment string is less than maximum meaningful byte length, could make sense.

    Did that in https://github.com/bitcoin/bitcoin/pull/34230

  10. glozow closed this on Jan 13, 2026

  11. glozow referenced this in commit 4aa80c3b5e on Jan 13, 2026
  12. maflcko commented at 10:56 am on January 16, 2026: member

    Same for mocked_descriptor_parse:

     0INFO: Running with entropic power schedule (0xFF, 100).
     1INFO: Seed: 1714490762
     2INFO: Loaded 1 modules   (657270 inline 8-bit counters): 657270 [0x6387296c, 0x639130e2), 
     3INFO: Loaded 1 PC tables (657270 PCs): 657270 [0x639130e4,0x63e16c94), 
     4INFO:     5257 files found in /ci_container_base/ci/scratch/qa-assets/fuzz_corpora/mocked_descriptor_parse
     5INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 974352 bytes
     6INFO: seed corpus: files: 5257 min: 1b max: 974352b total: 9424368b rss: 107Mb
     7[#512](/bitcoin-bitcoin/512/)	pulse  cov: 20310 ft: 76934 corp: 456/6161b exec/s: 128 rss: 127Mb
     8[#1024](/bitcoin-bitcoin/1024/)	pulse  cov: 22356 ft: 110101 corp: 892/17Kb exec/s: 51 rss: 150Mb
     9[#2048](/bitcoin-bitcoin/2048/)	pulse  cov: 23009 ft: 140010 corp: 1708/60Kb exec/s: 18 rss: 267Mb
    10Slowest unit: 10 s:
    11artifact_prefix='./'; Test unit written to ./slow-unit-ae69994a5ca2f513b9be415b80a63c2bec327907
    12Slowest unit: 14 s:
    13artifact_prefix='./'; Test unit written to ./slow-unit-56da48177d25572299ddf60d57a42d7bce5e317b
    14[#4096](/bitcoin-bitcoin/4096/)	pulse  cov: 23542 ft: 163125 corp: 3119/324Kb exec/s: 2 rss: 692Mb
    15Slowest unit: 19 s:
    16artifact_prefix='./'; Test unit written to ./slow-unit-692b9a7c56b3023f2d1ae3cd2a2e262c063ca1d0
    17Slowest unit: 22 s:
    18artifact_prefix='./'; Test unit written to ./slow-unit-7f143ed30724b1f950b1effcac76186fb0c2316e
    19Slowest unit: 27 s:
    20artifact_prefix='./'; Test unit written to ./slow-unit-f7551d1ab2f84f2272498105ddc4846698084e91
    21Slowest unit: 30 s:
    22artifact_prefix='./'; Test unit written to ./slow-unit-48e2486446d2af625b8da9509e58e367431961fc
    23Slowest unit: 37 s:
    24artifact_prefix='./'; Test unit written to ./slow-unit-d08c06428a2372c0b2a66de0904f87676fef8b5a
    25Slowest unit: 49 s:
    26artifact_prefix='./'; Test unit written to ./slow-unit-aacf8a4bfdedd7722dfcb9018cc1ff35eef35081
    27Slowest unit: 59 s:
    28artifact_prefix='./'; Test unit written to ./slow-unit-cbbf542b2ab8048d07baf5b4f6c0b7d8f669f68e
    29Slowest unit: 85 s:
    30artifact_prefix='./'; Test unit written to ./slow-unit-8d1c813c5535443d942e829beb3b0d5665556d02
    31Slowest unit: 96 s:
    32artifact_prefix='./'; Test unit written to ./slow-unit-80b3d5daccb3bb0dfc7b4e03dd0b50d36e59b6de
    33Slowest unit: 109 s:
    34artifact_prefix='./'; Test unit written to ./slow-unit-01a60537d94e3dd0d5e51c1f8a6ade5128760511
    35Slowest unit: 206 s:
    36artifact_prefix='./'; Test unit written to ./slow-unit-3e2a547e30dcd94a988ce20e8f632f1f75443626
    37Slowest unit: 294 s:
    38artifact_prefix='./'; Test unit written to ./slow-unit-53c9e6f4c21acda451de97231976f05ea46d6c35
    39/ci_container_base/src/base58.cpp:54:28: runtime error: unsigned integer overflow: 8388989 * 733 cannot be represented in type 'size_t' (aka 'unsigned int')
    40    [#0](/bitcoin-bitcoin/0/) 0x6035da73 in DecodeBase58(char const*, std::vector<unsigned char, std::allocator<unsigned char>>&, int) /ci_container_base/ci/scratch/build-i686-pc-linux-gnu/src/./base58.cpp:54:28
    41    [#1](/bitcoin-bitcoin/1/) 0x6035e8c8 in DecodeBase58Check(char const*, std::vector<unsigned char, std::allocator<unsigned char>>&, int) /ci_container_base/ci/scratch/build-i686-pc-linux-gnu/src/./base58.cpp:148:10
    42    [#2](/bitcoin-bitcoin/2/) 0x6035e8c8 in DecodeBase58Check(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&, std::vector<unsigned char, std::allocator<unsigned char>>&, int) /ci_container_base/ci/scratch/build-i686-pc-linux-gnu/src/./base58.cpp:168:12
    43    [#3](/bitcoin-bitcoin/3/) 0x604b34c4 in DecodeSecret(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>> const&) /ci_container_base/ci/scratch/build-i686-pc-linux-gnu/src/./key_io.cpp:217:9
    44    [#4](/bitcoin-bitcoin/4/) 0x60617343 in (anonymous namespace)::ParsePubkeyInner(unsigned int, std::span<char const, 4294967295u> const&, (anonymous namespace)::ParseScriptContext, FlatSigningProvider&, bool&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&) /ci_container_base/ci/scratch/build-i686-pc-linux-gnu/src/./script/descriptor.cpp:1818:20
    45    [#5](/bitcoin-bitcoin/5/) 0x605f5a2b in (anonymous namespace)::ParsePubkey(unsigned int&, std::span<char const, 4294967295u> const&, (anonymous namespace)::ParseScriptContext, FlatSigningProvider&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&) /ci_container_base/ci/scratch/build-i686-pc-linux-gnu/src/./script/descriptor.cpp:2007:16
    46    [#6](/bitcoin-bitcoin/6/) 0x605dfbf2 in (anonymous namespace)::ParseScript(unsigned int&, std::span<char const, 4294967295u>&, (anonymous namespace)::ParseScriptContext, FlatSigningProvider&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&) /ci_container_base/ci/scratch/build-i686-pc-linux-gnu/src/./script/descriptor.cpp:2363:30
    47    [#7](/bitcoin-bitcoin/7/) 0x605d981d in Parse(std::basic_string_view<char, std::char_traits<char>>, FlatSigningProvider&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char>>&, bool) /ci_container_base/ci/scratch/build-i686-pc-linux-gnu/src/./script/descriptor.cpp:2780:16
    48    [#8](/bitcoin-bitcoin/8/) 0x5fad4625 in mocked_descriptor_parse_fuzz_target(std::span<unsigned char const, 4294967295u>) /ci_container_base/ci/scratch/build-i686-pc-linux-gnu/src/test/fuzz/./test/fuzz/descriptor_parse.cpp:97:27
    49    [#9](/bitcoin-bitcoin/9/) 0x5f6b965a in void std::__invoke_impl<void, void (*&)(std::span<unsigned char const, 4294967295u>), std::span<unsigned char const, 4294967295u>>(std::__invoke_other, void (*&)(std::span<unsigned char const, 4294967295u>), std::span<unsigned char const, 4294967295u>&&) /usr/lib/gcc/i686-linux-gnu/14/../../../../include/c++/14/bits/invoke.h:61:14
    50    [#10](/bitcoin-bitcoin/10/) 0x5f6b965a in std::enable_if<is_invocable_r_v<void, void (*&)(std::span<unsigned char const, 4294967295u>), std::span<unsigned char const, 4294967295u>>, void>::type std::__invoke_r<void, void (*&)(std::span<unsigned char const, 4294967295u>), std::span<unsigned char const, 4294967295u>>(void (*&)(std::span<unsigned char const, 4294967295u>), std::span<unsigned char const, 4294967295u>&&) /usr/lib/gcc/i686-linux-gnu/14/../../../../include/c++/14/bits/invoke.h:111:2
    51    [#11](/bitcoin-bitcoin/11/) 0x5f6b965a in std::_Function_handler<void (std::span<unsigned char const, 4294967295u>), void (*)(std::span<unsigned char const, 4294967295u>)>::_M_invoke(std::_Any_data const&, std::span<unsigned char const, 4294967295u>&&) /usr/lib/gcc/i686-linux-gnu/14/../../../../include/c++/14/bits/std_function.h:290:9
    52    [#12](/bitcoin-bitcoin/12/) 0x6032e266 in std::function<void (std::span<unsigned char const, 4294967295u>)>::operator()(std::span<unsigned char const, 4294967295u>) const /usr/lib/gcc/i686-linux-gnu/14/../../../../include/c++/14/bits/std_function.h:591:9
    53    [#13](/bitcoin-bitcoin/13/) 0x6032e266 in test_one_input(std::span<unsigned char const, 4294967295u>) /ci_container_base/ci/scratch/build-i686-pc-linux-gnu/src/test/fuzz/util/./test/fuzz/fuzz.cpp:88:5
    54    [#14](/bitcoin-bitcoin/14/) 0x6032e266 in LLVMFuzzerTestOneInput /ci_container_base/ci/scratch/build-i686-pc-linux-gnu/src/test/fuzz/util/./test/fuzz/fuzz.cpp:216:5
    55    [#15](/bitcoin-bitcoin/15/) 0x5f5b7b28 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned int) (/ci_container_base/ci/scratch/build-i686-pc-linux-gnu/bin/fuzz+0xe1ab28) (BuildId: 4a3bad9138f9ac2be12a27f4001cebe27687bcce)
    56    [#16](/bitcoin-bitcoin/16/) 0x5f5b7092 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned int, bool, fuzzer::InputInfo*, bool, bool*) (/ci_container_base/ci/scratch/build-i686-pc-linux-gnu/bin/fuzz+0xe1a092) (BuildId: 4a3bad9138f9ac2be12a27f4001cebe27687bcce)
    57    [#17](/bitcoin-bitcoin/17/) 0x5f5b8f59 in fuzzer::Fuzzer::ReadAndExecuteSeedCorpora(std::vector<fuzzer::SizedFile, std::allocator<fuzzer::SizedFile>>&) (/ci_container_base/ci/scratch/build-i686-pc-linux-gnu/bin/fuzz+0xe1bf59) (BuildId: 4a3bad9138f9ac2be12a27f4001cebe27687bcce)
    58    [#18](/bitcoin-bitcoin/18/) 0x5f5b9482 in fuzzer::Fuzzer::Loop(std::vector<fuzzer::SizedFile, std::allocator<fuzzer::SizedFile>>&) (/ci_container_base/ci/scratch/build-i686-pc-linux-gnu/bin/fuzz+0xe1c482) (BuildId: 4a3bad9138f9ac2be12a27f4001cebe27687bcce)
    59    [#19](/bitcoin-bitcoin/19/) 0x5f5a5adb in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned int)) (/ci_container_base/ci/scratch/build-i686-pc-linux-gnu/bin/fuzz+0xe08adb) (BuildId: 4a3bad9138f9ac2be12a27f4001cebe27687bcce)
    60    [#20](/bitcoin-bitcoin/20/) 0x5f5d1ee7 in main (/ci_container_base/ci/scratch/build-i686-pc-linux-gnu/bin/fuzz+0xe34ee7) (BuildId: 4a3bad9138f9ac2be12a27f4001cebe27687bcce)
    61    [#21](/bitcoin-bitcoin/21/) 0xf3b39cc2  (/lib/i386-linux-gnu/libc.so.6+0x24cc2) (BuildId: fe186cb7d4de911234b23072a67be9931a6e562e)
    62    [#22](/bitcoin-bitcoin/22/) 0xf3b39d87 in __libc_start_main (/lib/i386-linux-gnu/libc.so.6+0x24d87) (BuildId: fe186cb7d4de911234b23072a67be9931a6e562e)
    63    [#23](/bitcoin-bitcoin/23/) 0x5f59a406 in _start (/ci_container_base/ci/scratch/build-i686-pc-linux-gnu/bin/fuzz+0xdfd406) (BuildId: 4a3bad9138f9ac2be12a27f4001cebe27687bcce)
    64
    65SUMMARY: UndefinedBehaviorSanitizer: unsigned-integer-overflow /ci_container_base/src/base58.cpp:54:28 
    66MS: 0 ; base unit: 0000000000000000000000000000000000000000
    67artifact_prefix='./'; Test unit written to ./crash-f5abf41608addcef3538da61d8096c2050235032
    68
    69⚠️ Failure generated from target with exit code 1: ['/ci_container_base/ci/scratch/build-i686-pc-linux-gnu/bin/fuzz', '-runs=1', PosixPath('/ci_container_base/ci/scratch/qa-assets/fuzz_corpora/mocked_descriptor_parse')]
    

    Same for

  13. maflcko commented at 11:57 am on January 16, 2026: member

    Can be reproduced locally with a 32-bit “simulation patch”:

    0diff --git a/src/base58.cpp b/src/base58.cpp
    1index 19a5bd3e55..bce2994db0 100644
    2--- a/src/base58.cpp
    3+++ b/src/base58.cpp
    4@@ -53,3 +53,3 @@ static const int8_t mapBase58[256] = {
    5     // Allocate enough space in big-endian base256 representation.
    6-    int size = strlen(psz) * 733 /1000 + 1; // log(58) / log(256), rounded up.
    7+    int size(uint32_t(std::strlen(psz)) * 733 / 1000 + 1); // log(58) / log(256), rounded up.
    8     std::vector<unsigned char> b256(size);
    

    And then:

    0curl -fLO 'https://github.com/bitcoin-core/qa-assets/raw/b5ad78e070e4cf36beb415d7b490d948d70ba73f/fuzz_corpora/mocked_descriptor_parse/f5abf41608addcef3538da61d8096c2050235032'
    1
    2FUZZ=mocked_descriptor_parse UBSAN_OPTIONS="suppressions=$(pwd)/test/sanitizer_suppressions/ubsan:print_stacktrace=1:halt_on_error=1:report_error_type=1" ./bld-cmake/bin/fuzz ./f5abf41608addcef3538da61d8096c2050235032
    


maflcko brunoerg

Labels
Wallet


github-metadata-mirror

This is a metadata mirror of the GitHub repository bitcoin/bitcoin. This site is not affiliated with GitHub. Content is generated from a GitHub metadata backup.
generated: 2026-01-22 09:13 UTC

This site is hosted by @0xB10C
More mirrored repositories can be found on mirror.b10c.me