[compiler-rt] r248325 - [asan] Versioned interceptor for pthread_create.
Evgeniy Stepanov via llvm-commits
llvm-commits at lists.llvm.org
Tue Sep 22 14:34:45 PDT 2015
Author: eugenis
Date: Tue Sep 22 16:34:44 2015
New Revision: 248325
URL: http://llvm.org/viewvc/llvm-project?rev=248325&view=rev
Log:
[asan] Versioned interceptor for pthread_create.
This fixes a crash in pthread_create on linux/i386 due to abi
incompatibility between intercepted and non-intercepted functions.
See the test case for more details.
Added:
compiler-rt/trunk/test/asan/TestCases/Linux/pthread_create_version.cc
Modified:
compiler-rt/trunk/lib/asan/asan_interceptors.cc
compiler-rt/trunk/lib/asan/asan_interceptors.h
compiler-rt/trunk/lib/interception/interception_linux.h
Modified: compiler-rt/trunk/lib/asan/asan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.cc?rev=248325&r1=248324&r2=248325&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_interceptors.cc Tue Sep 22 16:34:44 2015
@@ -27,6 +27,10 @@
#include "sanitizer_common/sanitizer_posix.h"
#endif
+#if defined(__i386) && SANITIZER_LINUX
+#define ASAN_PTHREAD_CREATE_VERSION "GLIBC_2.1"
+#endif
+
namespace __asan {
// Return true if we can quickly decide that the region is unpoisoned.
@@ -791,7 +795,11 @@ void InitializeAsanInterceptors() {
// Intercept threading-related functions
#if ASAN_INTERCEPT_PTHREAD_CREATE
+#if defined(ASAN_PTHREAD_CREATE_VERSION)
+ ASAN_INTERCEPT_FUNC_VER(pthread_create, ASAN_PTHREAD_CREATE_VERSION);
+#else
ASAN_INTERCEPT_FUNC(pthread_create);
+#endif
ASAN_INTERCEPT_FUNC(pthread_join);
#endif
Modified: compiler-rt/trunk/lib/asan/asan_interceptors.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.h?rev=248325&r1=248324&r2=248325&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_interceptors.h (original)
+++ compiler-rt/trunk/lib/asan/asan_interceptors.h Tue Sep 22 16:34:44 2015
@@ -98,6 +98,12 @@ DECLARE_REAL(int, sigaction, int signum,
if ((!INTERCEPT_FUNCTION(name) || !REAL(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))) \
+ VReport( \
+ 1, "AddressSanitizer: failed to intercept '" #name "@@" #ver "'\n"); \
+ } while (0)
#else
// OS X interceptors don't need to be initialized with INTERCEPT_FUNCTION.
#define ASAN_INTERCEPT_FUNC(name)
Modified: compiler-rt/trunk/lib/interception/interception_linux.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/interception/interception_linux.h?rev=248325&r1=248324&r2=248325&view=diff
==============================================================================
--- compiler-rt/trunk/lib/interception/interception_linux.h (original)
+++ compiler-rt/trunk/lib/interception/interception_linux.h Tue Sep 22 16:34:44 2015
@@ -35,12 +35,12 @@ void *GetFuncAddrVer(const char *func_na
(::__interception::uptr) & WRAP(func))
#if !defined(__ANDROID__) // android does not have dlvsym
-# define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \
- ::__interception::real_##func = (func##_f)(unsigned long) \
- ::__interception::GetFuncAddrVer(#func, symver)
+#define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \
+ (::__interception::real_##func = (func##_f)( \
+ unsigned long)::__interception::GetFuncAddrVer(#func, symver))
#else
-# define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \
- INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func)
+#define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \
+ INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func)
#endif // !defined(__ANDROID__)
#endif // INTERCEPTION_LINUX_H
Added: compiler-rt/trunk/test/asan/TestCases/Linux/pthread_create_version.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Linux/pthread_create_version.cc?rev=248325&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Linux/pthread_create_version.cc (added)
+++ compiler-rt/trunk/test/asan/TestCases/Linux/pthread_create_version.cc Tue Sep 22 16:34:44 2015
@@ -0,0 +1,23 @@
+// RUN: %clangxx_asan -std=c++11 %s -o %t && %run %t 2>&1
+// Regression test for the versioned pthread_create interceptor on linux/i386.
+// pthread_attr_init is not intercepted and binds to the new abi
+// pthread_create is intercepted; dlsym always returns the oldest version.
+// This results in a crash inside pthread_create in libc.
+
+#include <pthread.h>
+#include <stdlib.h>
+
+void *ThreadFunc(void *) { return nullptr; }
+
+int main() {
+ pthread_t t;
+ const size_t sz = 1024 * 1024;
+ void *p = malloc(sz);
+ pthread_attr_t attr;
+ pthread_attr_init(&attr);
+ pthread_attr_setstack(&attr, p, sz);
+ pthread_create(&t, &attr, ThreadFunc, nullptr);
+ pthread_join(t, nullptr);
+ free(p);
+ return 0;
+}
More information about the llvm-commits
mailing list