2

I'm catching an uninitialized read under Valgrind during a std::string compare. The program is being built without -march and -m, so we are in a core-x86_64 configuration which is SSE2-only. We would like limit the runtime library to SSE2, also.

The ld.so(8) man page documents LD_HWCAP_MASK, but it does not provide information on creating the mask. In fact, the description is the only place the "mask" is discussed.

LD_HWCAP_MASK (since glibc 2.1)
    Mask for hardware capabilities.

Here is a similar question but I am not quite following what is going on: Disable AVX-optimized functions in glibc (LD_HWCAP_MASK, /etc/ld.so.nohwcap) for valgrind . I can't imagine one needs to create source code patches and then recompile runtime libraries and loaders just to create a hardware mask. (But I might be missing something obvious).

How do I create a SSE2-only mask for x86_64?


Here is the head of the finding:

==4536== Conditional jump or move depends on uninitialised value(s)
==4536==    at 0x4C34C26: __memcmp_sse4_1 (vg_replace_strmem.c:1099)
==4536==    by 0x48B3B5: compare (char_traits.h:310)
==4536==    by 0x48B3B5: __gnu_cxx::__enable_if<std::__is_char<char>::__value, bool>::__type std::operator==<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&) (basic_string.h:6006)
==4536==    by 0x4F8E9C: operator!=<char, std::char_traits<char>, std::allocator<char> > (basic_string.h:6045)
...

And here is the source code causing the finding.

if (test == "EncryptXorDigest" && xorDigest != ciphertextXorDigest)
{
     ...
}

This is the only finding being generated by Valgrind. It is part of a torture test, and the strings are 128KB long.

When I perform the same test on an early 2000's 32-bit VIA C7-D with SSE and SSE2 only, the problem does not surface. __memcmp_sse4_1 has raised a lot of suspicion

The code is also clean under Asan, Bsan, UBsan, Coverity and Microsoft's Enterprise Analysis. The Valgrind test is the only one producing a finding.


Here is the system info.

  • OS: Fedora 26, x86_64, fully patched
  • Valgrind: valgrind-3.14.0.GIT (built from sources)
  • Glibc: ldd (GNU libc) 2.25
  • Compilers: GCC 4.8 - GCC 7.2
  • Compiler options: -DNDEBUG -g3 -O1 -DCRYPTOPP_VALGRIND

Nothing special happens with -DCRYPTOPP_VALGRIND. We enable more tests when this sort of testing occurs.

jww
  • 97,681
  • 90
  • 411
  • 885

0 Answers0