Skip to content

Commit 3478494

Browse files
committed
[libFuzzer] Unpoison parameters before calling user callback.
Summary: Fixes an MSan false positive when compiling with -fsanitize=memory,fuzzer. See google/oss-fuzz#2369 for more details. Reviewers: kcc Reviewed By: kcc Subscribers: llvm-commits, metzman, eugenis Tags: #llvm Differential Revision: https://reviews.llvm.org/D61753 llvm-svn: 360390
1 parent 9920213 commit 3478494

File tree

4 files changed

+37
-1
lines changed

4 files changed

+37
-1
lines changed

compiler-rt/lib/fuzzer/FuzzerExtFunctions.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,4 @@ EXT_FUNC(__sanitizer_set_report_fd, void, (void*), false);
4646
EXT_FUNC(__msan_scoped_disable_interceptor_checks, void, (), false);
4747
EXT_FUNC(__msan_scoped_enable_interceptor_checks, void, (), false);
4848
EXT_FUNC(__msan_unpoison, void, (const volatile void *, size_t size), false);
49+
EXT_FUNC(__msan_unpoison_param, void, (size_t n), false);

compiler-rt/lib/fuzzer/FuzzerLoop.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -542,6 +542,8 @@ void Fuzzer::ExecuteCallback(const uint8_t *Data, size_t Size) {
542542
memcpy(DataCopy, Data, Size);
543543
if (EF->__msan_unpoison)
544544
EF->__msan_unpoison(DataCopy, Size);
545+
if (EF->__msan_unpoison_param)
546+
EF->__msan_unpoison_param(2);
545547
if (CurrentUnitData && CurrentUnitData != Data)
546548
memcpy(CurrentUnitData, Data, Size);
547549
CurrentUnitSize = Size;
@@ -702,7 +704,7 @@ void Fuzzer::MutateAndTestOne() {
702704
break; // We will mutate this input more in the next rounds.
703705
}
704706
if (Options.ReduceDepth && !FoundUniqFeatures)
705-
break;
707+
break;
706708
}
707709
}
708710

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
2+
// See https://llvm.org/LICENSE.txt for license information.
3+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
4+
5+
// Triggers the bug described here:
6+
// https://github.com/google/oss-fuzz/issues/2369#issuecomment-490240627
7+
//
8+
// In a nutshell, MSan's parameter shadow does not get unpoisoned before calls
9+
// to LLVMFuzzerTestOneInput. This test case causes the parameter shadow to be
10+
// poisoned by the call to foo(), which will trigger an MSan false positive on
11+
// the Size == 0 check if the parameter shadow is still poisoned.
12+
#include <cstdint>
13+
#include <cstdio>
14+
#include <cstdlib>
15+
#include <cstring>
16+
17+
volatile int zero = 0;
18+
__attribute__((noinline)) int foo(int arg1, int arg2) { return zero; }
19+
20+
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
21+
if (Size == 0)
22+
return 0;
23+
24+
// Pass uninitialized values to foo(). Since foo doesn't do anything with
25+
// them, MSan should not report an error here.
26+
int a, b;
27+
return foo(a, b);
28+
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
REQUIRES: msan
2+
RUN: %msan_compiler %S/MsanParamUnpoison.cpp -o %t
3+
RUN: %run %t -seed=1 -runs=1000 2>&1 | FileCheck %s
4+
5+
CHECK-NOT: MemorySanitizer: use-of-uninitialized-value

0 commit comments

Comments
 (0)