From: Slava Barinov Date: Wed, 11 Apr 2018 09:57:23 +0000 (+0300) Subject: [ASan] Intercept mcheck and mprobe on Linux X-Git-Tag: accepted/tizen/base/20180413.181204^0 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=f4955bb607f6b1b73f7957e83388375064737359;p=platform%2Fupstream%2Flinaro-gcc.git [ASan] 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 git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@302001 91177308-0d34-0410-b5e6-96231b Change-Id: I310e0e06d0ad4450acf779630acfb71cde9ea1d2 Signed-off-by: Slava Barinov --- diff --git a/gcc/testsuite/gcc.dg/asan/mprobe.c b/gcc/testsuite/gcc.dg/asan/mprobe.c new file mode 100644 index 0000000..882a097 --- /dev/null +++ b/gcc/testsuite/gcc.dg/asan/mprobe.c @@ -0,0 +1,42 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=address" } */ + +#include +#include +#if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 2) +#include +#else +#define MCHECK_OK 0 +extern int mcheck(void (*abortfunc)(int mstatus)); +extern int mcheck_pedantic(void (*abortfunc)(int mstatus)); +extern 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(); + /* { dg-output "Success!\n" } */ + + if (mcheck_pedantic(NULL) != 0) { + fprintf(stderr, "mcheck_pedantic() failed\n"); + exit(EXIT_FAILURE); + } + + check_heap(); + /* { dg-output "Success!\n" } */ + + return 0; +} diff --git a/libsanitizer/lsan/lsan_interceptors.cc b/libsanitizer/lsan/lsan_interceptors.cc index 4b77ae6..6a01907 100644 --- a/libsanitizer/lsan/lsan_interceptors.cc +++ b/libsanitizer/lsan/lsan_interceptors.cc @@ -321,6 +321,20 @@ INTERCEPTOR(int, munmap, void *addr, size_t length) { return REAL(munmap)(addr, length); } +#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 + namespace __lsan { void InitializeInterceptors() { @@ -342,6 +356,11 @@ void InitializeInterceptors() { INTERCEPT_FUNCTION(mmap); INTERCEPT_FUNCTION(mmap64); INTERCEPT_FUNCTION(munmap); +#if SANITIZER_INTERCEPT_MCHECK_MPROBE + INTERCEPT_FUNCTION(mcheck); + INTERCEPT_FUNCTION(mcheck_pedantic); + INTERCEPT_FUNCTION(mprobe); +#endif // SANITIZER_INTERCEPT_MCHECK_MPROBE if (pthread_key_create(&g_thread_finalize_key, &thread_finalize)) { Report("LeakSanitizer: failed to create thread key.\n"); diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc b/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc index d3059f0..c6f1ae0 100644 --- a/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc +++ b/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc @@ -5917,6 +5917,27 @@ INTERCEPTOR(int, __lxstat64, int version, const char *path, void *buf) { // FIXME: add other *stat interceptor +#if SANITIZER_INTERCEPT_MCHECK_MPROBE +INTERCEPTOR(int, mcheck, void (*abortfunc)(int mstatus)) { + return 0; +} +#define INIT_MCHECK COMMON_INTERCEPT_FUNCTION(mcheck) + +INTERCEPTOR(int, mcheck_pedantic, void (*abortfunc)(int mstatus)) { + return 0; +} +#define INIT_MCHECK_PEDANTIC COMMON_INTERCEPT_FUNCTION(mcheck_pedantic) + +INTERCEPTOR(int, mprobe, void *ptr) { + return 0; +} +#define INIT_MPROBE COMMON_INTERCEPT_FUNCTION(mprobe) +#else +#define INIT_MCHECK +#define INIT_MCHECK_PEDANTIC +#define INIT_MPROBE +#endif // SANITIZER_INTERCEPT_MCHECK_MPROBE + static void InitializeCommonInterceptors() { static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1]; interceptor_metadata_map = new((void *)&metadata_mem) MetadataHashMap(); @@ -6114,4 +6135,7 @@ static void InitializeCommonInterceptors() { INIT___LXSTAT64; // FIXME: add other *stat interceptors. INIT___PRINTF_CHK; + INIT_MCHECK; + INIT_MCHECK_PEDANTIC; + INIT_MPROBE; } diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h b/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h index db1668e..0ee5ec2 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h +++ b/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h @@ -313,4 +313,5 @@ #define SANITIZER_INTERCEPT___XSTAT64 SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT___LXSTAT SANITIZER_INTERCEPT___XSTAT #define SANITIZER_INTERCEPT___LXSTAT64 SI_LINUX_NOT_ANDROID +#define SANITIZER_INTERCEPT_MCHECK_MPROBE SI_LINUX_NOT_ANDROID #endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H