Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[MSan] Introduce __msan_unpoison_param().
Summary: This allows libFuzzer to unpoison parameter shadow before calling LLVMFuzzerTestOneInput to eliminate the false positives described in google/oss-fuzz#2369. Reviewers: eugenis Reviewed By: eugenis Subscribers: llvm-commits, metzman, kcc Tags: #llvm Differential Revision: https://reviews.llvm.org/D61751 llvm-svn: 360379
- Loading branch information
Showing
4 changed files
with
58 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// Tests that __msan_unpoison_param() works as specified. To prevent MSan | ||
// instrumentation from modifying parameter shadow before each call to foo(), we | ||
// compile main() without MSan. | ||
|
||
// RUN: %clangxx_msan -fno-sanitize=memory -c %s -o %t-main.o | ||
// RUN: %clangxx_msan %t-main.o %s -o %t | ||
// RUN: %run %t | ||
|
||
#include <assert.h> | ||
#include <sanitizer/msan_interface.h> | ||
|
||
#if __has_feature(memory_sanitizer) | ||
|
||
__attribute__((noinline)) int bar(int a, int b) { | ||
volatile int zero = 0; | ||
return zero; | ||
} | ||
|
||
int foo(int a, int b, int unpoisoned_params) { | ||
if (unpoisoned_params == 0) { | ||
assert(__msan_test_shadow(&a, sizeof(a)) == 0); | ||
assert(__msan_test_shadow(&b, sizeof(b)) == 0); | ||
} else if (unpoisoned_params == 1) { | ||
assert(__msan_test_shadow(&a, sizeof(a)) == -1); | ||
assert(__msan_test_shadow(&b, sizeof(b)) == 0); | ||
} else if (unpoisoned_params == 2) { | ||
assert(__msan_test_shadow(&a, sizeof(a)) == -1); | ||
assert(__msan_test_shadow(&b, sizeof(b)) == -1); | ||
} | ||
|
||
// Poisons parameter shadow in TLS so that the next call from uninstrumented | ||
// main has params 1 and 2 poisoned no matter what. | ||
int x, y; | ||
return bar(x, y); | ||
} | ||
|
||
#else | ||
|
||
int foo(int, int, int); | ||
|
||
int main() { | ||
foo(0, 0, 2); // Poison parameters for next call. | ||
foo(0, 0, 0); // Check that both params are poisoned. | ||
__msan_unpoison_param(1); | ||
foo(0, 0, 1); // Check that only first param is unpoisoned. | ||
__msan_unpoison_param(2); | ||
foo(0, 0, 2); // Check that first and second params are unpoisoned. | ||
return 0; | ||
} | ||
|
||
#endif |