Is your feature request related to a problem? Please describe.
Both MemorySanitizer and Valgrind will only detect uninitialized memory if it is used for branching or IO.
E.g. the following program performs a computation using an uninitialized variable (a) but this won't trigger MSAN/Valgrind:
int main(void)
{
int a; int b = a + 10;
return 0;
}
Describe the solution you'd like
Call
extern "C" void __msan_check_mem_is_initialized(const volatile void *x, size_t size);
on the data to make MSAN evaluate it.
Describe alternatives you've considered
Alternative solution that also works with Valgrind: write the data to /dev/null:
#include <stdio.h>
int main(void)
{
int a; int b = a + 10;
FILE* fp = fopen("/dev/null", "wb");
fwrite(&b, sizeof(b), 1, fp);
fclose(fp);
return 0;
}
Additional context
Proposal: Create a wrapper for __msan_check_mem_is_initialized (as a C++ method), e.g.:
void TestMsan(const void* data, const size_t size) {
__msan_check_mem_is_initialized(x, size);
}
And use overloaded methods for special types, e.g.
void TestMsan(const std::string& s) {
TestMsan(s.data(), s.size());
}
Then edit all fuzzer harnesses and call TestMsan with the output of each non-void method.
E.g. the parse_script harness would become:
// Copyright (c) 2009-2020 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.
#include <core_io.h>
#include <script/script.h>
#include <test/fuzz/fuzz.h>
FUZZ_TARGET(parse_script)
{
const std::string script_string(buffer.begin(), buffer.end());
try {
TestMsan(ParseScript(script_string));
} catch (const std::runtime_error&) {
}
}
The same concept can be applied to the unit tests.