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

issue maflcko opened 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:

    export 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
    
    cmake -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
    
    cmake --build ./bld-cmake --parallel  $(nproc)
    
    curl -fLO 'https://github.com/bitcoin-core/qa-assets/raw/b5ad78e070e4cf36beb415d7b490d948d70ba73f/fuzz_corpora/scriptpubkeyman/1cf91e0c6bfff9dafcd4db5b0ba36b1e906f4cf5'
    
    UBSAN_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:

    /b-c/src/base58.cpp:54:28: runtime error: unsigned integer overflow: 8744655 * 733 cannot be represented in type 'size_t' (aka 'unsigned int')
        [#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
        [#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
        [#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
        [#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
        [#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
        [#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
        [#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
        [#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
        [#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
        [#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
        [#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
        [#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
        [#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
        [#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
        [#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
        [#15](/bitcoin-bitcoin/15/) 0x59821b80 in main /b-c/bld-cmake/src/test/fuzz/util/./test/fuzz/fuzz.cpp:271:13
        [#16](/bitcoin-bitcoin/16/) 0xf75a8cc2  (/lib/i386-linux-gnu/libc.so.6+0x24cc2) (BuildId: 2dc5f2945fad35c1b07d1a5a32520b3c41afaa75)
        [#17](/bitcoin-bitcoin/17/) 0xf75a8d87 in __libc_start_main (/lib/i386-linux-gnu/libc.so.6+0x24d87) (BuildId: 2dc5f2945fad35c1b07d1a5a32520b3c41afaa75)
        [#18](/bitcoin-bitcoin/18/) 0x58917db6 in _start (/b-c/bld-cmake/bin/fuzz+0x235ddb6) (BuildId: 7d8d83a77923f14e99c0de64acbc5f5bfc2cce9b)
    
    SUMMARY: 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:

        refactor: Use uint64_t over size_t for multiplications in DecodeBase58
    
    diff --git a/src/base58.cpp b/src/base58.cpp
    index 19a5bd3e55..5364b8276b 100644
    --- a/src/base58.cpp
    +++ b/src/base58.cpp
    @@ -51,7 +51,7 @@ static const int8_t mapBase58[256] = {
             psz++;
         }
         // Allocate enough space in big-endian base256 representation.
    -    int size = strlen(psz) * 733 /1000 + 1; // log(58) / log(256), rounded up.
    +    int size(uint64_t{std::strlen(psz)} * 733 / 1000 + 1); // log(58) / log(256), rounded up.
         std::vector<unsigned char> b256(size);
         // Process the characters.
         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:

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

    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:

    diff --git a/src/test/fuzz/util/descriptor.cpp b/src/test/fuzz/util/descriptor.cpp
    index 9e52e990a2..7c5e43206a 100644
    --- a/src/test/fuzz/util/descriptor.cpp
    +++ b/src/test/fuzz/util/descriptor.cpp
    @@ -62,7 +62,8 @@ std::optional<std::string> MockedDescriptorConverter::GetDescriptor(std::string_
                 if (i + 3 >= mocked_desc.size()) return {};
                 if (const auto idx = IdxFromHex(mocked_desc.substr(i + 1, 2))) {
                     desc += keys_str[*idx];
    -                i += 3;
    +               // Consume %ij (3 chars) + 1 separator. Prevents invalid consecutive placeholders like %00%01
    +                i += 4;
                 } 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:

    INFO: Running with entropic power schedule (0xFF, 100).
    INFO: Seed: 1714490762
    INFO: Loaded 1 modules   (657270 inline 8-bit counters): 657270 [0x6387296c, 0x639130e2), 
    INFO: Loaded 1 PC tables (657270 PCs): 657270 [0x639130e4,0x63e16c94), 
    INFO:     5257 files found in /ci_container_base/ci/scratch/qa-assets/fuzz_corpora/mocked_descriptor_parse
    INFO: -max_len is not provided; libFuzzer will not generate inputs larger than 974352 bytes
    INFO: seed corpus: files: 5257 min: 1b max: 974352b total: 9424368b rss: 107Mb
    [#512](/bitcoin-bitcoin/512/)	pulse  cov: 20310 ft: 76934 corp: 456/6161b exec/s: 128 rss: 127Mb
    [#1024](/bitcoin-bitcoin/1024/)	pulse  cov: 22356 ft: 110101 corp: 892/17Kb exec/s: 51 rss: 150Mb
    [#2048](/bitcoin-bitcoin/2048/)	pulse  cov: 23009 ft: 140010 corp: 1708/60Kb exec/s: 18 rss: 267Mb
    Slowest unit: 10 s:
    artifact_prefix='./'; Test unit written to ./slow-unit-ae69994a5ca2f513b9be415b80a63c2bec327907
    Slowest unit: 14 s:
    artifact_prefix='./'; Test unit written to ./slow-unit-56da48177d25572299ddf60d57a42d7bce5e317b
    [#4096](/bitcoin-bitcoin/4096/)	pulse  cov: 23542 ft: 163125 corp: 3119/324Kb exec/s: 2 rss: 692Mb
    Slowest unit: 19 s:
    artifact_prefix='./'; Test unit written to ./slow-unit-692b9a7c56b3023f2d1ae3cd2a2e262c063ca1d0
    Slowest unit: 22 s:
    artifact_prefix='./'; Test unit written to ./slow-unit-7f143ed30724b1f950b1effcac76186fb0c2316e
    Slowest unit: 27 s:
    artifact_prefix='./'; Test unit written to ./slow-unit-f7551d1ab2f84f2272498105ddc4846698084e91
    Slowest unit: 30 s:
    artifact_prefix='./'; Test unit written to ./slow-unit-48e2486446d2af625b8da9509e58e367431961fc
    Slowest unit: 37 s:
    artifact_prefix='./'; Test unit written to ./slow-unit-d08c06428a2372c0b2a66de0904f87676fef8b5a
    Slowest unit: 49 s:
    artifact_prefix='./'; Test unit written to ./slow-unit-aacf8a4bfdedd7722dfcb9018cc1ff35eef35081
    Slowest unit: 59 s:
    artifact_prefix='./'; Test unit written to ./slow-unit-cbbf542b2ab8048d07baf5b4f6c0b7d8f669f68e
    Slowest unit: 85 s:
    artifact_prefix='./'; Test unit written to ./slow-unit-8d1c813c5535443d942e829beb3b0d5665556d02
    Slowest unit: 96 s:
    artifact_prefix='./'; Test unit written to ./slow-unit-80b3d5daccb3bb0dfc7b4e03dd0b50d36e59b6de
    Slowest unit: 109 s:
    artifact_prefix='./'; Test unit written to ./slow-unit-01a60537d94e3dd0d5e51c1f8a6ade5128760511
    Slowest unit: 206 s:
    artifact_prefix='./'; Test unit written to ./slow-unit-3e2a547e30dcd94a988ce20e8f632f1f75443626
    Slowest unit: 294 s:
    artifact_prefix='./'; Test unit written to ./slow-unit-53c9e6f4c21acda451de97231976f05ea46d6c35
    /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')
        [#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
        [#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
        [#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
        [#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
        [#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
        [#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
        [#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
        [#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
        [#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
        [#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
        [#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
        [#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
        [#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
        [#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
        [#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
        [#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)
        [#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)
        [#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)
        [#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)
        [#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)
        [#20](/bitcoin-bitcoin/20/) 0x5f5d1ee7 in main (/ci_container_base/ci/scratch/build-i686-pc-linux-gnu/bin/fuzz+0xe34ee7) (BuildId: 4a3bad9138f9ac2be12a27f4001cebe27687bcce)
        [#21](/bitcoin-bitcoin/21/) 0xf3b39cc2  (/lib/i386-linux-gnu/libc.so.6+0x24cc2) (BuildId: fe186cb7d4de911234b23072a67be9931a6e562e)
        [#22](/bitcoin-bitcoin/22/) 0xf3b39d87 in __libc_start_main (/lib/i386-linux-gnu/libc.so.6+0x24d87) (BuildId: fe186cb7d4de911234b23072a67be9931a6e562e)
        [#23](/bitcoin-bitcoin/23/) 0x5f59a406 in _start (/ci_container_base/ci/scratch/build-i686-pc-linux-gnu/bin/fuzz+0xdfd406) (BuildId: 4a3bad9138f9ac2be12a27f4001cebe27687bcce)
    
    SUMMARY: UndefinedBehaviorSanitizer: unsigned-integer-overflow /ci_container_base/src/base58.cpp:54:28 
    MS: 0 ; base unit: 0000000000000000000000000000000000000000
    artifact_prefix='./'; Test unit written to ./crash-f5abf41608addcef3538da61d8096c2050235032
    
    ⚠️ 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":

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

    And then:

    curl -fLO 'https://github.com/bitcoin-core/qa-assets/raw/b5ad78e070e4cf36beb415d7b490d948d70ba73f/fuzz_corpora/mocked_descriptor_parse/f5abf41608addcef3538da61d8096c2050235032'
    
    FUZZ=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
    

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-04-13 18:12 UTC

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