summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHans Wennborg <hans@hanshq.net>2019-08-01 08:32:39 +0000
committerHans Wennborg <hans@hanshq.net>2019-08-01 08:32:39 +0000
commit6499bcc0e91d958fe0a58d35306a15265153fac3 (patch)
tree61a050fd5e6dc5aaf4346426fd29ee099ebce280
parentd15f1142f795ba0d739c1f636fd20be4ab2e8ebe (diff)
downloadcompiler-rt-6499bcc0e91d958fe0a58d35306a15265153fac3.tar.gz
Merging r367442:
------------------------------------------------------------------------ r367442 | arichardson | 2019-07-31 18:31:55 +0200 (Wed, 31 Jul 2019) | 30 lines [Sanitizer][ASAN][MSAN] Fix infinite recursion on FreeBSD Summary: MSAN was broken on FreeBSD by https://reviews.llvm.org/D55703: after this change accesses to the key variable call __tls_get_addr, which is intercepted. The interceptor then calls GetCurrentThread which calls MsanTSDGet which again calls __tls_get_addr, etc... Using the default implementation in the SANITIZER_FREEBSD case fixes MSAN for me. I then applied the same change to ASAN (introduced in https://reviews.llvm.org/D55596) but that did not work yet. In the ASAN case, we get infinite recursion again during initialization, this time because calling pthread_key_create() early on results in infinite recursion. pthread_key_create() calls sysctlbyname() which is intercepted but COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED returns true, so the interceptor calls internal_sysctlbyname() which then ends up calling the interceptor again. I fixed this issue by using dlsym() to get the libc version of sysctlbyname() instead. This fixes https://llvm.org/PR40761 Reviewers: vitalybuka, krytarowski, devnexen, dim, bsdjhb, #sanitizers, MaskRay Reviewed By: MaskRay Subscribers: MaskRay, emaste, kubamracek, jfb, #sanitizers, llvm-commits Tags: #sanitizers, #llvm Differential Revision: https://reviews.llvm.org/D65221 ------------------------------------------------------------------------ git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/branches/release_90@367524 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/asan/asan_posix.cc4
-rw-r--r--lib/msan/msan_linux.cc4
-rw-r--r--lib/sanitizer_common/sanitizer_linux.cc6
-rw-r--r--test/asan/TestCases/Posix/fread_fwrite.cc3
-rw-r--r--test/asan/TestCases/Posix/tsd_dtor_leak.cc2
-rw-r--r--test/msan/tzset.cc1
6 files changed, 9 insertions, 11 deletions
diff --git a/lib/asan/asan_posix.cc b/lib/asan/asan_posix.cc
index 5c5e0359a..f3fbda07a 100644
--- a/lib/asan/asan_posix.cc
+++ b/lib/asan/asan_posix.cc
@@ -39,8 +39,8 @@ void AsanOnDeadlySignal(int signo, void *siginfo, void *context) {
// ---------------------- TSD ---------------- {{{1
-#if SANITIZER_NETBSD || SANITIZER_FREEBSD
-// Thread Static Data cannot be used in early init on NetBSD and FreeBSD.
+#if SANITIZER_NETBSD
+// Thread Static Data cannot be used in early init on NetBSD.
// Reuse the Asan TSD API for compatibility with existing code
// with an alternative implementation.
diff --git a/lib/msan/msan_linux.cc b/lib/msan/msan_linux.cc
index 3b6e6cb85..056783088 100644
--- a/lib/msan/msan_linux.cc
+++ b/lib/msan/msan_linux.cc
@@ -174,8 +174,8 @@ void InstallAtExitHandler() {
// ---------------------- TSD ---------------- {{{1
-#if SANITIZER_NETBSD || SANITIZER_FREEBSD
-// Thread Static Data cannot be used in early init on NetBSD and FreeBSD.
+#if SANITIZER_NETBSD
+// Thread Static Data cannot be used in early init on NetBSD.
// Reuse the MSan TSD API for compatibility with existing code
// with an alternative implementation.
diff --git a/lib/sanitizer_common/sanitizer_linux.cc b/lib/sanitizer_common/sanitizer_linux.cc
index 88ab0979b..455fd4c86 100644
--- a/lib/sanitizer_common/sanitizer_linux.cc
+++ b/lib/sanitizer_common/sanitizer_linux.cc
@@ -779,7 +779,11 @@ int internal_sysctl(const int *name, unsigned int namelen, void *oldp,
#if SANITIZER_FREEBSD
int internal_sysctlbyname(const char *sname, void *oldp, uptr *oldlenp,
const void *newp, uptr newlen) {
- return sysctlbyname(sname, oldp, (size_t *)oldlenp, newp, (size_t)newlen);
+ static decltype(sysctlbyname) *real = nullptr;
+ if (!real)
+ real = (decltype(sysctlbyname) *)dlsym(RTLD_NEXT, "sysctlbyname");
+ CHECK(real);
+ return real(sname, oldp, (size_t *)oldlenp, newp, (size_t)newlen);
}
#endif
#endif
diff --git a/test/asan/TestCases/Posix/fread_fwrite.cc b/test/asan/TestCases/Posix/fread_fwrite.cc
index 640248860..c06292604 100644
--- a/test/asan/TestCases/Posix/fread_fwrite.cc
+++ b/test/asan/TestCases/Posix/fread_fwrite.cc
@@ -1,9 +1,6 @@
// RUN: %clangxx_asan -g %s -o %t
// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-FWRITE
// RUN: not %run %t 1 2>&1 | FileCheck %s --check-prefix=CHECK-FREAD
-//
-// On FreeBSD stack overflow error instead
-// XFAIL: freebsd
#include <stdio.h>
#include <stdlib.h>
diff --git a/test/asan/TestCases/Posix/tsd_dtor_leak.cc b/test/asan/TestCases/Posix/tsd_dtor_leak.cc
index 26109fe1a..860f3459e 100644
--- a/test/asan/TestCases/Posix/tsd_dtor_leak.cc
+++ b/test/asan/TestCases/Posix/tsd_dtor_leak.cc
@@ -3,8 +3,6 @@
// RUN: %clangxx_asan -O1 %s -pthread -o %t
// RUN: %env_asan_opts=quarantine_size_mb=0 %run %t
// XFAIL: x86_64-netbsd
-// Assertion fails
-// XFAIL: x86_64-freebsd
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
diff --git a/test/msan/tzset.cc b/test/msan/tzset.cc
index 86805cd56..05915e047 100644
--- a/test/msan/tzset.cc
+++ b/test/msan/tzset.cc
@@ -1,5 +1,4 @@
// RUN: %clangxx_msan -O0 %s -o %t && %run %t
-// XFAIL: freebsd
#include <stdlib.h>
#include <string.h>