mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-18 19:06:44 +00:00
[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
This commit is contained in:
parent
5833bb280f
commit
91c166cbb0
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user