https://github.com/devnexen updated https://github.com/llvm/llvm-project/pull/125389
>From e40672e8137c0546b1604795901ccea8b15f7932 Mon Sep 17 00:00:00 2001 From: David Carlier <devne...@gmail.com> Date: Sun, 2 Feb 2025 09:36:50 +0000 Subject: [PATCH 1/3] [compiler-rt][rtsan] porting the sanitizer to FreeBSD. Most of the apple api exceptions also apply to freebsd, however to create a per-thread realtime context pthread api cannot be used since freebsd calls calloc in _thr_alloc(). --- compiler-rt/lib/rtsan/rtsan_context.cpp | 16 ++++++++++++++++ .../lib/rtsan/rtsan_interceptors_posix.cpp | 4 ++-- .../tests/rtsan_test_interceptors_posix.cpp | 4 +++- 3 files changed, 21 insertions(+), 3 deletions(-) diff --git a/compiler-rt/lib/rtsan/rtsan_context.cpp b/compiler-rt/lib/rtsan/rtsan_context.cpp index 536d62e81e2fb66..dacc9b6dedf4029 100644 --- a/compiler-rt/lib/rtsan/rtsan_context.cpp +++ b/compiler-rt/lib/rtsan/rtsan_context.cpp @@ -19,6 +19,7 @@ using namespace __sanitizer; using namespace __rtsan; +#if !SANITIZER_FREEBSD static pthread_key_t context_key; static pthread_once_t key_once = PTHREAD_ONCE_INIT; @@ -43,6 +44,21 @@ static __rtsan::Context &GetContextForThisThreadImpl() { return *current_thread_context; } +#else + +// On FreeBSD, pthread api cannot be used as calloc is called under the hood +// at library initialization time. +static __thread Context *ctx = nullptr; + +static __rtsan::Context &GetContextForThisThreadImpl() { + if (ctx == nullptr) { + ctx = static_cast<Context *>(MmapOrDie(sizeof(Context), "RtsanContext")); + new (ctx) Context(); + } + + return *ctx; +} +#endif __rtsan::Context::Context() = default; diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp index 83e6cdd4a009410..b76413dc2e462f1 100644 --- a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp +++ b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp @@ -939,7 +939,7 @@ INTERCEPTOR(int, msync, void *addr, size_t length, int flag) { return REAL(msync)(addr, length, flag); } -#if SANITIZER_APPLE +#if SANITIZER_APPLE || SANITIZER_FREEBSD INTERCEPTOR(int, mincore, const void *addr, size_t length, char *vec) { #else INTERCEPTOR(int, mincore, void *addr, size_t length, unsigned char *vec) { @@ -1334,7 +1334,7 @@ INTERCEPTOR(ssize_t, process_vm_writev, pid_t pid, // the test. Revisit this in the future, but hopefully intercepting fork/exec is // enough to dissuade usage of wait by proxy. -#if SANITIZER_APPLE +#if SANITIZER_APPLE || SANITIZER_FREEBSD #define INT_TYPE_SYSCALL int #else #define INT_TYPE_SYSCALL long diff --git a/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp b/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp index 075f5974b7562a8..e5290ababec6685 100644 --- a/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp +++ b/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp @@ -280,7 +280,7 @@ TEST_F(RtsanOpenedMmapTest, MsyncDiesWhenRealtime) { } TEST_F(RtsanOpenedMmapTest, MincoreDiesWhenRealtime) { -#if SANITIZER_APPLE +#if SANITIZER_APPLE || SANITIZER_FREEBSD std::vector<char> vec(GetSize() / 1024); #else std::vector<unsigned char> vec(GetSize() / 1024); @@ -1539,6 +1539,7 @@ TEST_F(KqueueTest, KeventDiesWhenRealtime) { ExpectNonRealtimeSurvival(Func); } +#if SANITIZER_APPLE TEST_F(KqueueTest, Kevent64DiesWhenRealtime) { struct kevent64_s event; EV_SET64(&event, 0, EVFILT_READ, EV_ADD, 0, 0, 0, 0, 0); @@ -1551,6 +1552,7 @@ TEST_F(KqueueTest, Kevent64DiesWhenRealtime) { ExpectRealtimeDeath(Func, "kevent64"); ExpectNonRealtimeSurvival(Func); } +#endif // SANITIZER_APPLE #endif // SANITIZER_INTERCEPT_KQUEUE #if SANITIZER_LINUX >From 05ad49c3ff4fd185ab0618a1cfd05c2a86f36dcc Mon Sep 17 00:00:00 2001 From: David Carlier <devne...@gmail.com> Date: Sun, 2 Feb 2025 09:38:52 +0000 Subject: [PATCH 2/3] freebsd clang frontend update. --- clang/lib/Driver/ToolChains/FreeBSD.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/clang/lib/Driver/ToolChains/FreeBSD.cpp b/clang/lib/Driver/ToolChains/FreeBSD.cpp index a6d859f0ebfec23..baabfabf26267f6 100644 --- a/clang/lib/Driver/ToolChains/FreeBSD.cpp +++ b/clang/lib/Driver/ToolChains/FreeBSD.cpp @@ -497,6 +497,7 @@ SanitizerMask FreeBSD::getSupportedSanitizers() const { Res |= SanitizerKind::PointerCompare; Res |= SanitizerKind::PointerSubtract; Res |= SanitizerKind::Vptr; + Res |= SanitizerKind::Realtime; if (IsAArch64 || IsX86_64 || IsMIPS64) { Res |= SanitizerKind::Leak; Res |= SanitizerKind::Thread; >From 49a4564ac7a3e3042178817c407d32086bb543d3 Mon Sep 17 00:00:00 2001 From: David Carlier <devne...@gmail.com> Date: Fri, 7 Feb 2025 13:19:37 +0000 Subject: [PATCH 3/3] using pthread api for context creation. but disabling mmap interception for this platform, which is the root cause of the previous infinite call recursion. --- compiler-rt/cmake/config-ix.cmake | 4 ++-- compiler-rt/lib/rtsan/rtsan_context.cpp | 16 ---------------- .../lib/rtsan/rtsan_interceptors_posix.cpp | 16 ++++++++++++++-- .../tests/rtsan_test_interceptors_posix.cpp | 4 ++++ 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake index cf729c3adb1f5f5..b981db24942217f 100644 --- a/compiler-rt/cmake/config-ix.cmake +++ b/compiler-rt/cmake/config-ix.cmake @@ -793,7 +793,7 @@ else() endif() if (COMPILER_RT_HAS_SANITIZER_COMMON AND RTSAN_SUPPORTED_ARCH AND - OS_NAME MATCHES "Darwin|Linux") + OS_NAME MATCHES "Darwin|Linux|FreeBSD") set(COMPILER_RT_HAS_RTSAN TRUE) else() set(COMPILER_RT_HAS_RTSAN FALSE) @@ -850,7 +850,7 @@ else() endif() if (COMPILER_RT_HAS_SANITIZER_COMMON AND TYSAN_SUPPORTED_ARCH AND - OS_NAME MATCHES "Linux|Darwin") + OS_NAME MATCHES "Linux|Darwin") set(COMPILER_RT_HAS_TYSAN TRUE) else() set(COMPILER_RT_HAS_TYSAN FALSE) diff --git a/compiler-rt/lib/rtsan/rtsan_context.cpp b/compiler-rt/lib/rtsan/rtsan_context.cpp index dacc9b6dedf4029..536d62e81e2fb66 100644 --- a/compiler-rt/lib/rtsan/rtsan_context.cpp +++ b/compiler-rt/lib/rtsan/rtsan_context.cpp @@ -19,7 +19,6 @@ using namespace __sanitizer; using namespace __rtsan; -#if !SANITIZER_FREEBSD static pthread_key_t context_key; static pthread_once_t key_once = PTHREAD_ONCE_INIT; @@ -44,21 +43,6 @@ static __rtsan::Context &GetContextForThisThreadImpl() { return *current_thread_context; } -#else - -// On FreeBSD, pthread api cannot be used as calloc is called under the hood -// at library initialization time. -static __thread Context *ctx = nullptr; - -static __rtsan::Context &GetContextForThisThreadImpl() { - if (ctx == nullptr) { - ctx = static_cast<Context *>(MmapOrDie(sizeof(Context), "RtsanContext")); - new (ctx) Context(); - } - - return *ctx; -} -#endif __rtsan::Context::Context() = default; diff --git a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp index b76413dc2e462f1..8d4a16edb2ca8b6 100644 --- a/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp +++ b/compiler-rt/lib/rtsan/rtsan_interceptors_posix.cpp @@ -864,11 +864,18 @@ INTERCEPTOR(void *, pvalloc, size_t size) { #define RTSAN_MAYBE_INTERCEPT_PVALLOC #endif +#if !SANITIZER_FREEBSD +// enabling this interception on freebsd leads to infinite recursion +// on pthread lib initialization INTERCEPTOR(void *, mmap, void *addr, size_t length, int prot, int flags, int fd, off_t offset) { __rtsan_notify_intercepted_call("mmap"); return REAL(mmap)(addr, length, prot, flags, fd, offset); } +#define RTSAN_MAYBE_INTERCEPT_MMAP INTERCEPT_FUNCTION(mmap) +#else +#define RTSAN_MAYBE_INTERCEPT_MMAP +#endif // !SANITIZER_FREEBSD #if SANITIZER_INTERCEPT_MMAP64 INTERCEPTOR(void *, mmap64, void *addr, size_t length, int prot, int flags, @@ -907,10 +914,15 @@ INTERCEPTOR(void *, mremap, void *oaddr, size_t olength, size_t nlength, #define RTSAN_MAYBE_INTERCEPT_MREMAP #endif +#if !SANITIZER_FREEBSD INTERCEPTOR(int, munmap, void *addr, size_t length) { __rtsan_notify_intercepted_call("munmap"); return REAL(munmap)(addr, length); } +#define RTSAN_MAYBE_INTERCEPT_MUNMAP INTERCEPT_FUNCTION(munmap) +#else +#define RTSAN_MAYBE_INTERCEPT_MUNMAP +#endif #if !SANITIZER_APPLE INTERCEPTOR(int, madvise, void *addr, size_t length, int flag) { @@ -1381,10 +1393,10 @@ void __rtsan::InitializeInterceptors() { INTERCEPT_FUNCTION(valloc); RTSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC; INTERCEPT_FUNCTION(posix_memalign); - INTERCEPT_FUNCTION(mmap); + RTSAN_MAYBE_INTERCEPT_MMAP; RTSAN_MAYBE_INTERCEPT_MMAP64; RTSAN_MAYBE_INTERCEPT_MREMAP; - INTERCEPT_FUNCTION(munmap); + RTSAN_MAYBE_INTERCEPT_MUNMAP; RTSAN_MAYBE_INTERCEPT_MADVISE; RTSAN_MAYBE_INTERCEPT_POSIX_MADVISE; INTERCEPT_FUNCTION(mprotect); diff --git a/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp b/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp index e5290ababec6685..6047a16aa1ff760 100644 --- a/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp +++ b/compiler-rt/lib/rtsan/tests/rtsan_test_interceptors_posix.cpp @@ -188,6 +188,7 @@ TEST(TestRtsanInterceptors, PvallocDiesWhenRealtime) { } #endif +#if !SANITIZER_FREEBSD TEST(TestRtsanInterceptors, MmapDiesWhenRealtime) { auto Func = []() { void *_ = mmap(nullptr, 8, PROT_READ | PROT_WRITE, @@ -196,6 +197,7 @@ TEST(TestRtsanInterceptors, MmapDiesWhenRealtime) { ExpectRealtimeDeath(Func, MAYBE_APPEND_64("mmap")); ExpectNonRealtimeSurvival(Func); } +#endif #if SANITIZER_LINUX TEST(TestRtsanInterceptors, MremapDiesWhenRealtime) { @@ -207,6 +209,7 @@ TEST(TestRtsanInterceptors, MremapDiesWhenRealtime) { } #endif +#if !SANITIZER_FREEBSD TEST(TestRtsanInterceptors, MunmapDiesWhenRealtime) { void *ptr = mmap(nullptr, 8, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); @@ -216,6 +219,7 @@ TEST(TestRtsanInterceptors, MunmapDiesWhenRealtime) { ExpectRealtimeDeath(Func, "munmap"); ExpectNonRealtimeSurvival(Func); } +#endif class RtsanOpenedMmapTest : public RtsanFileTest { protected: _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits