From 91c166cbb035a22db1b0ebee7bb760c55c80b77d Mon Sep 17 00:00:00 2001 From: Julian Lettner Date: Wed, 1 May 2019 20:57:59 +0000 Subject: [Sanitizer] Reland "Cleanup INTERCEPT_FUNCTION macro" On Linux both version of the INTERCEPT_FUNCTION macro now return true when interception was successful. Adapt and cleanup some usages. Also note that `&(func) == &WRAP(func)` is a link-time property, but we do a runtime check. Tested on Linux and macOS. Previous attempt reverted by: 5642c3feb03d020dc06a62e3dc54f3206a97a391 This attempt to bring order to the interceptor macro goes the other direction and aligns the Linux implementation with the way things are done on Windows. Reviewed By: vitalybuka, rnk Differential Revision: https://reviews.llvm.org/D61358 llvm-svn: 359725 --- compiler-rt/lib/asan/asan_interceptors.h | 4 ++-- compiler-rt/lib/interception/interception_linux.cc | 24 ++++++++++++++------- compiler-rt/lib/interception/interception_linux.h | 25 ++++++++++++---------- .../interception/tests/interception_linux_test.cc | 15 +++++-------- compiler-rt/lib/msan/msan_interceptors.cc | 4 ++-- compiler-rt/lib/tsan/rtl/tsan_interceptors.cc | 13 ++++++----- 6 files changed, 45 insertions(+), 40 deletions(-) (limited to 'compiler-rt') diff --git a/compiler-rt/lib/asan/asan_interceptors.h b/compiler-rt/lib/asan/asan_interceptors.h index 903ab5991e9..2792e2f14bc 100644 --- a/compiler-rt/lib/asan/asan_interceptors.h +++ b/compiler-rt/lib/asan/asan_interceptors.h @@ -122,12 +122,12 @@ DECLARE_REAL(char*, strstr, const char *s1, const char *s2) #if !SANITIZER_MAC #define ASAN_INTERCEPT_FUNC(name) \ do { \ - if ((!INTERCEPT_FUNCTION(name) || !REAL(name))) \ + if (!INTERCEPT_FUNCTION(name)) \ VReport(1, "AddressSanitizer: failed to intercept '" #name "'\n"); \ } while (0) #define ASAN_INTERCEPT_FUNC_VER(name, ver) \ do { \ - if ((!INTERCEPT_FUNCTION_VER(name, ver) || !REAL(name))) \ + if (!INTERCEPT_FUNCTION_VER(name, ver)) \ VReport( \ 1, "AddressSanitizer: failed to intercept '" #name "@@" #ver "'\n"); \ } while (0) diff --git a/compiler-rt/lib/interception/interception_linux.cc b/compiler-rt/lib/interception/interception_linux.cc index d019d482d6d..d07f060b5b6 100644 --- a/compiler-rt/lib/interception/interception_linux.cc +++ b/compiler-rt/lib/interception/interception_linux.cc @@ -33,13 +33,7 @@ static int StrCmp(const char *s1, const char *s2) { } #endif -bool GetRealFunctionAddress(const char *func_name, uptr *func_addr, - uptr real, uptr wrapper) { - *func_addr = (uptr)GetFuncAddr(func_name); - return real == wrapper; -} - -void *GetFuncAddr(const char *name) { +static void *GetFuncAddr(const char *name) { #if SANITIZER_NETBSD // FIXME: Find a better way to handle renames if (StrCmp(name, "sigaction")) @@ -57,11 +51,25 @@ void *GetFuncAddr(const char *name) { return addr; } +bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func, + uptr wrapper) { + void *addr = GetFuncAddr(name); + *ptr_to_real = (uptr)addr; + return addr && (func == wrapper); +} + // Android and Solaris do not have dlvsym #if !SANITIZER_ANDROID && !SANITIZER_SOLARIS && !SANITIZER_OPENBSD -void *GetFuncAddrVer(const char *name, const char *ver) { +static void *GetFuncAddr(const char *name, const char *ver) { return dlvsym(RTLD_NEXT, name, ver); } + +bool InterceptFunction(const char *name, const char *ver, uptr *ptr_to_real, + uptr func, uptr wrapper) { + void *addr = GetFuncAddr(name, ver); + *ptr_to_real = (uptr)addr; + return addr && (func == wrapper); +} #endif // !SANITIZER_ANDROID } // namespace __interception diff --git a/compiler-rt/lib/interception/interception_linux.h b/compiler-rt/lib/interception/interception_linux.h index 4c60bd88090..e578da0cf64 100644 --- a/compiler-rt/lib/interception/interception_linux.h +++ b/compiler-rt/lib/interception/interception_linux.h @@ -22,24 +22,27 @@ #define INTERCEPTION_LINUX_H namespace __interception { -// returns true if a function with the given name was found. -bool GetRealFunctionAddress(const char *func_name, uptr *func_addr, - uptr real, uptr wrapper); -void *GetFuncAddr(const char *name); -void *GetFuncAddrVer(const char *name, const char *ver); +bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func, + uptr wrapper); +bool InterceptFunction(const char *name, const char *ver, uptr *ptr_to_real, + uptr func, uptr wrapper); } // namespace __interception -#define INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func) \ - ::__interception::GetRealFunctionAddress( \ - #func, (::__interception::uptr *)&__interception::PTR_TO_REAL(func), \ - (::__interception::uptr) & (func), \ +#define INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func) \ + ::__interception::InterceptFunction( \ + #func, \ + (::__interception::uptr *) & REAL(func), \ + (::__interception::uptr) & (func), \ (::__interception::uptr) & WRAP(func)) // Android, Solaris and OpenBSD do not have dlvsym #if !SANITIZER_ANDROID && !SANITIZER_SOLARIS && !SANITIZER_OPENBSD #define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \ - (::__interception::real_##func = (func##_type)( \ - unsigned long)::__interception::GetFuncAddrVer(#func, symver)) + ::__interception::InterceptFunction( \ + #func, symver, \ + (::__interception::uptr *) & REAL(func), \ + (::__interception::uptr) & (func), \ + (::__interception::uptr) & WRAP(func)) #else #define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \ INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func) diff --git a/compiler-rt/lib/interception/tests/interception_linux_test.cc b/compiler-rt/lib/interception/tests/interception_linux_test.cc index 5a1ca6ecbf5..3e859cb1a55 100644 --- a/compiler-rt/lib/interception/tests/interception_linux_test.cc +++ b/compiler-rt/lib/interception/tests/interception_linux_test.cc @@ -33,24 +33,19 @@ INTERCEPTOR(int, isdigit, int d) { namespace __interception { -TEST(Interception, GetRealFunctionAddress) { +TEST(Interception, InterceptFunction) { uptr malloc_address = 0; - EXPECT_TRUE(GetRealFunctionAddress("malloc", &malloc_address, 0, 0)); + EXPECT_TRUE(InterceptFunction("malloc", &malloc_address, 0, 0)); EXPECT_NE(0U, malloc_address); + EXPECT_FALSE(InterceptFunction("malloc", &malloc_address, 0, 1)); uptr dummy_address = 0; - EXPECT_TRUE( - GetRealFunctionAddress("dummy_doesnt_exist__", &dummy_address, 0, 0)); + EXPECT_FALSE(InterceptFunction("dummy_doesnt_exist__", &dummy_address, 0, 0)); EXPECT_EQ(0U, dummy_address); } -TEST(Interception, GetFuncAddr) { - EXPECT_NE(GetFuncAddr("malloc"), nullptr); - EXPECT_EQ(GetFuncAddr("does_not_exist"), nullptr); -} - TEST(Interception, Basic) { - INTERCEPT_FUNCTION(isdigit); + EXPECT_TRUE(INTERCEPT_FUNCTION(isdigit)); // After interception, the counter should be incremented. InterceptorFunctionCalled = 0; diff --git a/compiler-rt/lib/msan/msan_interceptors.cc b/compiler-rt/lib/msan/msan_interceptors.cc index f67cfe48916..af9d1402976 100644 --- a/compiler-rt/lib/msan/msan_interceptors.cc +++ b/compiler-rt/lib/msan/msan_interceptors.cc @@ -1248,13 +1248,13 @@ int OnExit() { #define MSAN_INTERCEPT_FUNC(name) \ do { \ - if ((!INTERCEPT_FUNCTION(name) || !REAL(name))) \ + if (!INTERCEPT_FUNCTION(name)) \ VReport(1, "MemorySanitizer: failed to intercept '" #name "'\n"); \ } while (0) #define MSAN_INTERCEPT_FUNC_VER(name, ver) \ do { \ - if ((!INTERCEPT_FUNCTION_VER(name, ver) || !REAL(name))) \ + if (!INTERCEPT_FUNCTION_VER(name, ver)) \ VReport( \ 1, "MemorySanitizer: failed to intercept '" #name "@@" #ver "'\n"); \ } while (0) diff --git a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc index 062a3622b37..e8908ac98ed 100644 --- a/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc +++ b/compiler-rt/lib/tsan/rtl/tsan_interceptors.cc @@ -2659,14 +2659,13 @@ void InitializeInterceptors() { #if !SANITIZER_MAC // We can not use TSAN_INTERCEPT to get setjmp addr, // because it does &setjmp and setjmp is not present in some versions of libc. - using __interception::GetRealFunctionAddress; - GetRealFunctionAddress(TSAN_STRING_SETJMP, - (uptr*)&REAL(setjmp_symname), 0, 0); - GetRealFunctionAddress("_setjmp", (uptr*)&REAL(_setjmp), 0, 0); - GetRealFunctionAddress(TSAN_STRING_SIGSETJMP, - (uptr*)&REAL(sigsetjmp_symname), 0, 0); + using __interception::InterceptFunction; + InterceptFunction(TSAN_STRING_SETJMP, (uptr*)&REAL(setjmp_symname), 0, 0); + InterceptFunction("_setjmp", (uptr*)&REAL(_setjmp), 0, 0); + InterceptFunction(TSAN_STRING_SIGSETJMP, (uptr*)&REAL(sigsetjmp_symname), 0, + 0); #if !SANITIZER_NETBSD - GetRealFunctionAddress("__sigsetjmp", (uptr*)&REAL(__sigsetjmp), 0, 0); + InterceptFunction("__sigsetjmp", (uptr*)&REAL(__sigsetjmp), 0, 0); #endif #endif -- cgit v1.2.1