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:
0int main(void)
1{
2 int a; int b = a + 10;
3 return 0;
4}
Describe the solution you’d like
Call
0extern "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
:
0#include <stdio.h>
1
2int main(void)
3{
4 int a; int b = a + 10;
5 FILE* fp = fopen("/dev/null", "wb");
6 fwrite(&b, sizeof(b), 1, fp);
7 fclose(fp);
8 return 0;
9}
Additional context
Proposal: Create a wrapper for __msan_check_mem_is_initialized
(as a C++ method), e.g.:
0void TestMsan(const void* data, const size_t size) {
1 __msan_check_mem_is_initialized(x, size);
2}
And use overloaded methods for special types, e.g.
0void TestMsan(const std::string& s) {
1 TestMsan(s.data(), s.size());
2}
Then edit all fuzzer harnesses and call TestMsan
with the output of each non-void method.
E.g. the parse_script harness would become:
0// Copyright (c) 2009-2020 The Bitcoin Core developers
1// Distributed under the MIT software license, see the accompanying
2// file COPYING or http://www.opensource.org/licenses/mit-license.php.
3
4#include <core_io.h>
5#include <script/script.h>
6#include <test/fuzz/fuzz.h>
7
8FUZZ_TARGET(parse_script)
9{
10 const std::string script_string(buffer.begin(), buffer.end());
11 try {
12 TestMsan(ParseScript(script_string));
13 } catch (const std::runtime_error&) {
14 }
15}
The same concept can be applied to the unit tests.