From 726701b0ed67c400bc41fe08feb8a19668b59cbf Mon Sep 17 00:00:00 2001 From: Maxim Ostapenko Date: Wed, 3 May 2017 07:09:10 +0000 Subject: [PATCH] [sanitizer] Intercept mcheck and mprobe on Linux This patch addresses https://github.com/google/sanitizers/issues/804. Users can use mcheck and mprobe functions to verify heap state so we should intercept them to avoid breakage of valid code. Differential Revision: https://reviews.llvm.org/D32589 llvm-svn: 302001 --- compiler-rt/lib/lsan/lsan_interceptors.cc | 14 ++++++++ .../sanitizer_common_interceptors.inc | 14 ++++++++ .../sanitizer_platform_interceptors.h | 1 + .../sanitizer_common/TestCases/Linux/mprobe.cc | 42 ++++++++++++++++++++++ 4 files changed, 71 insertions(+) create mode 100644 compiler-rt/test/sanitizer_common/TestCases/Linux/mprobe.cc diff --git a/compiler-rt/lib/lsan/lsan_interceptors.cc b/compiler-rt/lib/lsan/lsan_interceptors.cc index fe1f49b..9e39a7d 100644 --- a/compiler-rt/lib/lsan/lsan_interceptors.cc +++ b/compiler-rt/lib/lsan/lsan_interceptors.cc @@ -185,6 +185,20 @@ INTERCEPTOR(void, cfree, void *p) ALIAS(WRAPPER_NAME(free)); #define LSAN_MAYBE_INTERCEPT_CFREE #endif // SANITIZER_INTERCEPT_CFREE +#if SANITIZER_INTERCEPT_MCHECK_MPROBE +INTERCEPTOR(int, mcheck, void (*abortfunc)(int mstatus)) { + return 0; +} + +INTERCEPTOR(int, mcheck_pedantic, void (*abortfunc)(int mstatus)) { + return 0; +} + +INTERCEPTOR(int, mprobe, void *ptr) { + return 0; +} +#endif // SANITIZER_INTERCEPT_MCHECK_MPROBE + #define OPERATOR_NEW_BODY \ ENSURE_LSAN_INITED; \ GET_STACK_TRACE_MALLOC; \ diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc index 4fe1ac8..53204b4 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -6142,6 +6142,20 @@ INTERCEPTOR(int, getloadavg, double *loadavg, int nelem) { #define INIT_GETLOADAVG #endif +#if SANITIZER_INTERCEPT_MCHECK_MPROBE +INTERCEPTOR(int, mcheck, void (*abortfunc)(int mstatus)) { + return 0; +} + +INTERCEPTOR(int, mcheck_pedantic, void (*abortfunc)(int mstatus)) { + return 0; +} + +INTERCEPTOR(int, mprobe, void *ptr) { + return 0; +} +#endif + static void InitializeCommonInterceptors() { static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1]; interceptor_metadata_map = new((void *)&metadata_mem) MetadataHashMap(); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h index a583e98..e5644ef 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -339,5 +339,6 @@ #define SANITIZER_INTERCEPT_CFREE (!SI_FREEBSD && !SI_MAC) #define SANITIZER_INTERCEPT_ALIGNED_ALLOC (!SI_MAC) #define SANITIZER_INTERCEPT_MALLOC_USABLE_SIZE (!SI_MAC) +#define SANITIZER_INTERCEPT_MCHECK_MPROBE SI_LINUX_NOT_ANDROID #endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H diff --git a/compiler-rt/test/sanitizer_common/TestCases/Linux/mprobe.cc b/compiler-rt/test/sanitizer_common/TestCases/Linux/mprobe.cc new file mode 100644 index 0000000..57e5ba5 --- /dev/null +++ b/compiler-rt/test/sanitizer_common/TestCases/Linux/mprobe.cc @@ -0,0 +1,42 @@ +// RUN: %clangxx %s -o %t && %run %t 2>&1 | FileCheck %s +// UNSUPPORTED: android + +#include +#include +#if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 2) +#include +#else +#define MCHECK_OK 0 +extern "C" int mcheck(void (*abortfunc)(int mstatus)); +extern "C" int mcheck_pedantic(void (*abortfunc)(int mstatus)); +extern "C" int mprobe(void *ptr); +#endif + +void check_heap() { + void *p = malloc(1000); + int res = mprobe(p); + if (res == MCHECK_OK) + printf("Success!\n"); + free(p); +} + +int main(int argc, char *argv[]) { + void *p; + if (mcheck(NULL) != 0) { + fprintf(stderr, "mcheck() failed\n"); + exit(EXIT_FAILURE); + } + + check_heap(); + // CHECK: Success! + + if (mcheck_pedantic(NULL) != 0) { + fprintf(stderr, "mcheck_pedantic() failed\n"); + exit(EXIT_FAILURE); + } + + check_heap(); + // CHECK: Success! + + return 0; +} -- 2.7.4