diff options
author | Slava Barinov <v.barinov@samsung.com> | 2018-04-11 12:57:23 +0300 |
---|---|---|
committer | Slava Barinov <v.barinov@samsung.com> | 2018-04-11 15:03:38 +0300 |
commit | f4955bb607f6b1b73f7957e83388375064737359 (patch) | |
tree | c55f1fbee821f862208a8d81f4890a6069c3c0e7 | |
parent | f5000d69fa0211b873c58f5902853032da22d1b6 (diff) | |
download | linaro-gcc-f4955bb607f6b1b73f7957e83388375064737359.tar.gz linaro-gcc-f4955bb607f6b1b73f7957e83388375064737359.tar.bz2 linaro-gcc-f4955bb607f6b1b73f7957e83388375064737359.zip |
[ASan] Intercept mcheck and mprobe on Linuxsubmit/tizen_base/20180417.073401submit/tizen_base/20180412.024656accepted/tizen/base/20180420.170848accepted/tizen/base/20180413.181204
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 <v.barinov@samsung.com>
-rw-r--r-- | gcc/testsuite/gcc.dg/asan/mprobe.c | 42 | ||||
-rw-r--r-- | libsanitizer/lsan/lsan_interceptors.cc | 19 | ||||
-rw-r--r-- | libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc | 24 | ||||
-rw-r--r-- | libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h | 1 |
4 files changed, 86 insertions, 0 deletions
diff --git a/gcc/testsuite/gcc.dg/asan/mprobe.c b/gcc/testsuite/gcc.dg/asan/mprobe.c new file mode 100644 index 00000000000..882a09716c6 --- /dev/null +++ b/gcc/testsuite/gcc.dg/asan/mprobe.c @@ -0,0 +1,42 @@ +/* { dg-do run } */ +/* { dg-options "-fsanitize=address" } */ + +#include <stdio.h> +#include <stdlib.h> +#if defined(__GLIBC_PREREQ) && __GLIBC_PREREQ(2, 2) +#include <mcheck.h> +#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 4b77ae67de8..6a019073118 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 d3059f0c2f7..c6f1ae086cf 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 db1668e4773..0ee5ec261a7 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 |