Skip to content

MemorySanitizer complains about unitialized variable in RPC method names #17620

@Sjors

Description

@Sjors

I'm trying to get --with-sanitizers=memory to work on Ubuntu Bionic, since it might be useful to prevent stuff like #17568 and #17449.

I installed LLVM 9 and clang using the instructions here. I then configured with:

./configure --enable-debug --with-sanitizers=memory CXX=clang++-9 CC=clang-9

I can build just fine, but when I run bitcoind or bitcoin-cli it immediately bails out:

src/bitcoin-cli
Uninitialized bytes in MemcmpInterceptorCommon at offset 0 inside [0x705000000080, 11)
==25188==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x55734b322d9e in memcmp (/home/dev/bitcoin/src/bitcoin-cli+0x5ad9e)
    #1 0x7f633267abc7 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::compare(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) const (/usr/lib/x86_64-linux-gnu/libstdc++.so.6+0x126bc7)
    #2 0x55734b3e1042 in bool std::operator<<char, std::char_traits<char>, std::allocator<char> >(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/basic_string.h:6097:20
    #3 0x55734b3e0e13 in bool std::operator<<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int>(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> const&, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/stl_pair.h:455:24
    #4 0x55734b3e05bc in std::less<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> >::operator()(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> const&, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> const&) const /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/stl_function.h:386:20
    #5 0x55734b3e35e7 in std::_Rb_tree<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int>, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int>, std::_Identity<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> >, std::less<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> > >::_M_get_insert_unique_pos(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/stl_tree.h:2038:13
    #6 0x55734b3e2df0 in std::pair<std::_Rb_tree_iterator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> >, bool> std::_Rb_tree<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int>, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int>, std::_Identity<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> >, std::less<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> > >::_M_insert_unique<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> >(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int>&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/stl_tree.h:2091:4
    #7 0x55734b3db513 in std::set<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int>, std::less<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int> > >::insert(std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, int>&&) /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/stl_set.h:511:9
    #8 0x55734b3d8de9 in CRPCConvertTable::CRPCConvertTable() /home/dev/bitcoin/src/rpc/client.cpp:200:17
    #9 0x55734b30dd8a in __cxx_global_var_init.165 /home/dev/bitcoin/src/rpc/client.cpp:207:25
    #10 0x55734b30de22 in _GLOBAL__sub_I_client.cpp /home/dev/bitcoin/src/rpc/client.cpp
    #11 0x55734b58b10c in __libc_csu_init (/home/dev/bitcoin/src/bitcoin-cli+0x2c310c)
    #12 0x7f63317c2b27 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:266
    #13 0x55734b312cf9 in _start (/home/dev/bitcoin/src/bitcoin-cli+0x4acf9)

SUMMARY: MemorySanitizer: use-of-uninitialized-value (/home/dev/bitcoin/src/bitcoin-cli+0x5ad9e) in memcmp
Exiting

The relevant code (line 200) doesn't look wrong at first glance:

bitcoin/src/rpc/client.cpp

Lines 194 to 205 in d8a6662

CRPCConvertTable::CRPCConvertTable()
{
const unsigned int n_elem =
(sizeof(vRPCConvertParams) / sizeof(vRPCConvertParams[0]));
for (unsigned int i = 0; i < n_elem; i++) {
members.insert(std::make_pair(vRPCConvertParams[i].methodName,
vRPCConvertParams[i].paramIdx));
membersByName.insert(std::make_pair(vRPCConvertParams[i].methodName,
vRPCConvertParams[i].paramName));
}
}

The bitcoind issue seems similar:

src/bitcoind 
==25862==WARNING: MemorySanitizer: use-of-uninitialized-value
    #0 0x56472f55a4e0 in std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<CRPCCommand const*, std::allocator<CRPCCommand const*> > >, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<CRPCCommand const*, std::allocator<CRPCCommand const*> > > >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<CRPCCommand const*, std::allocator<CRPCCommand const*> > > > >::_M_lower_bound(std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<CRPCCommand const*, std::allocator<CRPCCommand const*> > > >*, std::_Rb_tree_node_base*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/stl_tree.h:1871:7
    #1 0x56472f55a24b in std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<CRPCCommand const*, std::allocator<CRPCCommand const*> > >, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<CRPCCommand const*, std::allocator<CRPCCommand const*> > > >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<CRPCCommand const*, std::allocator<CRPCCommand const*> > > > >::lower_bound(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/stl_tree.h:1187:16
    #2 0x56472f559519 in std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<CRPCCommand const*, std::allocator<CRPCCommand const*> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<CRPCCommand const*, std::allocator<CRPCCommand const*> > > > >::lower_bound(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/stl_map.h:1233:21
    #3 0x56472f4ee06d in std::map<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::vector<CRPCCommand const*, std::allocator<CRPCCommand const*> >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<CRPCCommand const*, std::allocator<CRPCCommand const*> > > > >::operator[](std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&) /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/stl_map.h:489:17
    #4 0x56472f4e3291 in CRPCTable::CRPCTable() /home/dev/bitcoin/src/rpc/server.cpp:255:9
    #5 0x56472ec17dda in __cxx_global_var_init.44 /home/dev/bitcoin/src/rpc/server.cpp:499:11
    #6 0x56472ec17e9a in _GLOBAL__sub_I_server.cpp /home/dev/bitcoin/src/rpc/server.cpp
    #7 0x564730ad1dac in __libc_csu_init (/home/dev/bitcoin/src/bitcoind+0x1f19dac)
    #8 0x7f4033472b27 in __libc_start_main /build/glibc-OTsEL5/glibc-2.27/csu/../csu/libc-start.c:266
    #9 0x56472ec3b659 in _start (/home/dev/bitcoin/src/bitcoind+0x83659)

SUMMARY: MemorySanitizer: use-of-uninitialized-value /usr/bin/../lib/gcc/x86_64-linux-gnu/7.4.0/../../../../include/c++/7.4.0/bits/stl_tree.h:1871:7 in std::_Rb_tree<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<CRPCCommand const*, std::allocator<CRPCCommand const*> > >, std::_Select1st<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<CRPCCommand const*, std::allocator<CRPCCommand const*> > > >, std::less<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > >, std::allocator<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vector<CRPCCommand const*, std::allocator<CRPCCommand const*> > > > >::_M_lower_bound(std::_Rb_tree_node<std::pair<std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const, std::vec
Exiting

Relevant code (line 255):

bitcoin/src/rpc/server.cpp

Lines 247 to 257 in d8a6662

CRPCTable::CRPCTable()
{
unsigned int vcidx;
for (vcidx = 0; vcidx < (sizeof(vRPCCommands) / sizeof(vRPCCommands[0])); vcidx++)
{
const CRPCCommand *pcmd;
pcmd = &vRPCCommands[vcidx];
mapCommands[pcmd->name].push_back(pcmd);
}
}

Maybe this is just a wild goose chase, if it turns out this sanitizer gets triggered all over the place. But @practicalswift successfully used it, so maybe theres' a secret sauce?

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions