forked from OSchip/llvm-project
[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 llvm-svn: 367442
This commit is contained in:
parent
af44f18ad6
commit
a4ea27de92
|
@ -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.
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
// RUN: %clangxx_msan -O0 %s -o %t && %run %t
|
||||
// XFAIL: freebsd
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
|
Loading…
Reference in New Issue