From 373d6ed7cf24e28de441cfeef4d14c4c0a20c905 Mon Sep 17 00:00:00 2001 From: Matt Morehouse Date: Fri, 6 Jul 2018 17:10:51 +0000 Subject: [PATCH] [MSan] Add functions to enable/disable interceptor checks. Summary: The motivation for this change is to make libFuzzer+MSan possible without instrumenting libFuzzer. See https://github.com/google/sanitizers/issues/958. Reviewers: eugenis Reviewed By: eugenis Subscribers: llvm-commits, kcc Differential Revision: https://reviews.llvm.org/D48890 llvm-svn: 336447 --- .../include/sanitizer/msan_interface.h | 8 +++ compiler-rt/lib/msan/msan_interceptors.cc | 3 ++ .../lib/msan/msan_interface_internal.h | 6 +++ compiler-rt/test/msan/scoped-interceptors.cc | 52 +++++++++++++++++++ 4 files changed, 69 insertions(+) create mode 100644 compiler-rt/test/msan/scoped-interceptors.cc diff --git a/compiler-rt/include/sanitizer/msan_interface.h b/compiler-rt/include/sanitizer/msan_interface.h index a87c954c15ec..0509551bbd17 100644 --- a/compiler-rt/include/sanitizer/msan_interface.h +++ b/compiler-rt/include/sanitizer/msan_interface.h @@ -104,6 +104,14 @@ extern "C" { copy. Source and destination regions can overlap. */ void __msan_copy_shadow(const volatile void *dst, const volatile void *src, size_t size); + + /* Disables uninitialized memory checks in interceptors. */ + void __msan_scoped_disable_interceptor_checks(void); + + /* Re-enables uninitialized memory checks in interceptors after a previous + call to __msan_scoped_disable_interceptor_checks. */ + void __msan_scoped_enable_interceptor_checks(void); + #ifdef __cplusplus } // extern "C" #endif diff --git a/compiler-rt/lib/msan/msan_interceptors.cc b/compiler-rt/lib/msan/msan_interceptors.cc index 48d038131190..b3429bcf06b5 100644 --- a/compiler-rt/lib/msan/msan_interceptors.cc +++ b/compiler-rt/lib/msan/msan_interceptors.cc @@ -60,6 +60,9 @@ DECLARE_REAL(void *, memset, void *dest, int c, uptr n) // True if this is a nested interceptor. static THREADLOCAL int in_interceptor_scope; +void __msan_scoped_disable_interceptor_checks() { ++in_interceptor_scope; } +void __msan_scoped_enable_interceptor_checks() { --in_interceptor_scope; } + struct InterceptorScope { InterceptorScope() { ++in_interceptor_scope; } ~InterceptorScope() { --in_interceptor_scope; } diff --git a/compiler-rt/lib/msan/msan_interface_internal.h b/compiler-rt/lib/msan/msan_interface_internal.h index c6990db243c1..9a67cbc9b5f8 100644 --- a/compiler-rt/lib/msan/msan_interface_internal.h +++ b/compiler-rt/lib/msan/msan_interface_internal.h @@ -174,6 +174,12 @@ void __msan_set_death_callback(void (*callback)(void)); SANITIZER_INTERFACE_ATTRIBUTE void __msan_copy_shadow(void *dst, const void *src, uptr size); + +SANITIZER_INTERFACE_ATTRIBUTE +void __msan_scoped_disable_interceptor_checks(); + +SANITIZER_INTERFACE_ATTRIBUTE +void __msan_scoped_enable_interceptor_checks(); } // extern "C" #endif // MSAN_INTERFACE_INTERNAL_H diff --git a/compiler-rt/test/msan/scoped-interceptors.cc b/compiler-rt/test/msan/scoped-interceptors.cc new file mode 100644 index 000000000000..fc7d4578482b --- /dev/null +++ b/compiler-rt/test/msan/scoped-interceptors.cc @@ -0,0 +1,52 @@ +// RUN: %clangxx_msan %s -o %t +// RUN: %run %t --disable-checks 0 2>&1 | FileCheck --check-prefix=DISABLED --allow-empty %s +// RUN: %run %t --disable-checks 1 2>&1 | FileCheck --check-prefix=DISABLED --allow-empty %s +// RUN: %run %t --disable-checks 2 2>&1 | FileCheck --check-prefix=DISABLED --allow-empty %s +// RUN: %run %t --disable-checks 3 2>&1 | FileCheck --check-prefix=DISABLED --allow-empty %s +// RUN: not %run %t --reenable-checks 0 2>&1 | FileCheck --check-prefix=CASE-0 %s +// RUN: not %run %t --reenable-checks 1 2>&1 | FileCheck --check-prefix=CASE-1 %s +// RUN: not %run %t --reenable-checks 2 2>&1 | FileCheck --check-prefix=CASE-2 %s +// RUN: not %run %t --reenable-checks 3 2>&1 | FileCheck --check-prefix=CASE-3 %s + +#include +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + assert(argc == 3); + __msan_scoped_disable_interceptor_checks(); + if (strcmp(argv[1], "--reenable-checks") == 0) + __msan_scoped_enable_interceptor_checks(); + + char uninit[7]; + switch (argv[2][0]) { + case '0': { + char *copy = strndup(uninit, sizeof(uninit)); // BOOM + free(copy); + break; + // CASE-0: Uninitialized bytes in __interceptor_strndup + } + case '1': { + puts(uninit); // BOOM + puts(uninit); // Ensure previous call did not enable interceptor checks. + break; + // CASE-1: Uninitialized bytes in __interceptor_puts + } + case '2': { + int cmp = memcmp(uninit, uninit, sizeof(uninit)); // BOOM + break; + // CASE-2: Uninitialized bytes in __interceptor_memcmp + } + case '3': { + size_t len = strlen(uninit); // BOOM + break; + // CASE-3: Uninitialized bytes in __interceptor_strlen + } + default: assert(0); + } + // DISABLED-NOT: Uninitialized bytes + return 0; +} + -- GitLab