Index: compiler-rt/lib/fuzzer/FuzzerDriver.cpp =================================================================== --- compiler-rt/lib/fuzzer/FuzzerDriver.cpp +++ compiler-rt/lib/fuzzer/FuzzerDriver.cpp @@ -537,6 +537,8 @@ EF = new ExternalFunctions(); if (EF->LLVMFuzzerInitialize) EF->LLVMFuzzerInitialize(argc, argv); + if (EF->__msan_disable_interceptor_checks) + EF->__msan_disable_interceptor_checks(); const Vector Args(*argv, *argv + *argc); assert(!Args.empty()); ProgName = new std::string(Args[0]); Index: compiler-rt/lib/fuzzer/FuzzerExtFunctions.def =================================================================== --- compiler-rt/lib/fuzzer/FuzzerExtFunctions.def +++ compiler-rt/lib/fuzzer/FuzzerExtFunctions.def @@ -46,3 +46,6 @@ EXT_FUNC(__sanitizer_set_report_fd, void, (void*), false); EXT_FUNC(__sanitizer_dump_coverage, void, (const uintptr_t *, uintptr_t), false); +EXT_FUNC(__msan_disable_interceptor_checks, void, (), false); +EXT_FUNC(__msan_reenable_interceptor_checks, void, (), false); +EXT_FUNC(__msan_unpoison, void, (const volatile void *, size_t size), false); Index: compiler-rt/lib/fuzzer/FuzzerLoop.cpp =================================================================== --- compiler-rt/lib/fuzzer/FuzzerLoop.cpp +++ compiler-rt/lib/fuzzer/FuzzerLoop.cpp @@ -179,6 +179,8 @@ void Fuzzer::DumpCurrentUnit(const char *Prefix) { if (!CurrentUnitData) return; // Happens when running individual inputs. + if (EF->__msan_disable_interceptor_checks) + EF->__msan_disable_interceptor_checks(); MD.PrintMutationSequence(); Printf("; base unit: %s\n", Sha1ToString(BaseSha1).c_str()); size_t UnitSize = CurrentUnitSize; @@ -188,6 +190,8 @@ } WriteUnitToFileWithPrefix({CurrentUnitData, CurrentUnitData + UnitSize}, Prefix); + if (EF->__msan_reenable_interceptor_checks) + EF->__msan_reenable_interceptor_checks(); } NO_SANITIZE_MEMORY @@ -512,6 +516,8 @@ assert(InFuzzingThread()); if (SMR.IsClient()) SMR.WriteByteArray(Data, Size); + if (EF->__msan_unpoison) + EF->__msan_unpoison(Data, Size); // We copy the contents of Unit into a separate heap buffer // so that we reliably find buffer overflows in it. uint8_t *DataCopy = new uint8_t[Size]; @@ -519,6 +525,8 @@ if (CurrentUnitData && CurrentUnitData != Data) memcpy(CurrentUnitData, Data, Size); CurrentUnitSize = Size; + if (EF->__msan_reenable_interceptor_checks) + EF->__msan_reenable_interceptor_checks(); AllocTracer.Start(Options.TraceMalloc); UnitStartTime = system_clock::now(); TPC.ResetMaps(); @@ -529,6 +537,8 @@ (void)Res; assert(Res == 0); HasMoreMallocsThanFrees = AllocTracer.Stop(); + if (EF->__msan_disable_interceptor_checks) + EF->__msan_disable_interceptor_checks(); if (!LooseMemeq(DataCopy, Data, Size)) CrashOnOverwrittenData(); CurrentUnitSize = 0; Index: compiler-rt/test/fuzzer/lit.cfg =================================================================== --- compiler-rt/test/fuzzer/lit.cfg +++ compiler-rt/test/fuzzer/lit.cfg @@ -49,7 +49,7 @@ libfuzzer_src_root = os.path.join(config.compiler_rt_src_root, "lib", "fuzzer") config.substitutions.append(('%libfuzzer_src', libfuzzer_src_root)) -def generate_compiler_cmd(is_cpp=True, fuzzer_enabled=True): +def generate_compiler_cmd(is_cpp=True, fuzzer_enabled=True, msan_enabled=False): compiler_cmd = config.clang extra_cmd = config.target_flags if config.clang and config.stdlib == 'libc++': @@ -63,7 +63,10 @@ link_cmd = '-lstdc++' std_cmd = '--driver-mode=g++ -std=c++11' if is_cpp else '' - sanitizers = ['address'] + if msan_enabled: + sanitizers = ['memory'] + else: + sanitizers = ['address'] if fuzzer_enabled: sanitizers.append('fuzzer') sanitizers_cmd = ('-fsanitize=%s' % ','.join(sanitizers)) @@ -93,6 +96,10 @@ generate_compiler_cmd(is_cpp=False, fuzzer_enabled=False) )) +config.substitutions.append(('%msan_compiler', + generate_compiler_cmd(is_cpp=True, fuzzer_enabled=True, msan_enabled=True) + )) + if config.host_os == 'Darwin': if config.target_arch in ["x86_64", "x86_64h"]: config.parallelism_group = "darwin-64bit-sanitizer" Index: compiler-rt/test/fuzzer/msan.test =================================================================== --- /dev/null +++ compiler-rt/test/fuzzer/msan.test @@ -0,0 +1,20 @@ +RUN: %msan_compiler %S/SimpleTest.cpp -o %t +RUN: not %run %t -seed=1 -runs=10000000 2>&1 | FileCheck %s --check-prefix=NO-REPORT + +RUN: %msan_compiler %S/SimpleCmpTest.cpp -o %t +RUN: not %run %t -seed=1 -runs=10000000 2>&1 | FileCheck %s --check-prefix=NO-REPORT + +RUN: %msan_compiler %S/MemcmpTest.cpp -o %t +RUN: not %run %t -seed=1 -runs=10000000 2>&1 | FileCheck %s --check-prefix=NO-REPORT + +RUN: %msan_compiler %S/StrcmpTest.cpp -o %t +RUN: not %run %t -seed=1 -runs=10000000 2>&1 | FileCheck %s --check-prefix=NO-REPORT + +NO-REPORT-NOT: MemorySanitizer +NO-REPORT: BINGO + + +RUN: %msan_compiler %S/BufferOverflowOnInput.cpp -o %t +RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=REPORT + +REPORT: MemorySanitizer: use-of-uninitialized-value