[libcxx-commits] [llvm] [lldb] [clang-tools-extra] [libcxx] [compiler-rt] [lld] [mlir] [libunwind] [libcxxabi] [flang] [libc] [clang] [asan] Install `pthread_atfork` (PR #75290)
Vitaly Buka via libcxx-commits
libcxx-commits at lists.llvm.org
Wed Dec 13 13:38:38 PST 2023
https://github.com/vitalybuka updated https://github.com/llvm/llvm-project/pull/75290
>From 2d98fe9115e37c60fd568008c27038015f28c7e3 Mon Sep 17 00:00:00 2001
From: Vitaly Buka <vitalybuka at google.com>
Date: Tue, 12 Dec 2023 22:59:06 -0800
Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20change?=
=?UTF-8?q?s=20to=20main=20this=20commit=20is=20based=20on?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.4
[skip ci]
---
.../include/sanitizer/hwasan_interface.h | 4 ++++
compiler-rt/lib/hwasan/hwasan.cpp | 2 ++
compiler-rt/lib/hwasan/hwasan.h | 6 ++---
.../lib/hwasan/hwasan_interface_internal.h | 3 +++
compiler-rt/lib/lsan/lsan.cpp | 1 +
compiler-rt/lib/lsan/lsan.h | 1 +
compiler-rt/lib/lsan/lsan_common.cpp | 3 +++
compiler-rt/lib/lsan/lsan_common.h | 4 ++++
compiler-rt/lib/lsan/lsan_fuchsia.cpp | 1 +
compiler-rt/lib/lsan/lsan_posix.cpp | 18 ++++++++++++++
compiler-rt/test/hwasan/TestCases/tag-ptr.cpp | 24 +++++++++++++++++++
.../TestCases/Posix/fork_threaded.c | 2 +-
.../sanitizer_common/sanitizer_specific.h | 13 ++++++++++
13 files changed, 78 insertions(+), 4 deletions(-)
create mode 100644 compiler-rt/test/hwasan/TestCases/tag-ptr.cpp
diff --git a/compiler-rt/include/sanitizer/hwasan_interface.h b/compiler-rt/include/sanitizer/hwasan_interface.h
index abe310c0666948..407f488a24a617 100644
--- a/compiler-rt/include/sanitizer/hwasan_interface.h
+++ b/compiler-rt/include/sanitizer/hwasan_interface.h
@@ -44,6 +44,10 @@ void SANITIZER_CDECL __hwasan_tag_memory(const volatile void *p,
void *SANITIZER_CDECL __hwasan_tag_pointer(const volatile void *p,
unsigned char tag);
+/// Get tag from the pointer.
+unsigned char SANITIZER_CDECL
+__hwasan_get_tag_from_pointer(const volatile void *p);
+
// Set memory tag from the current SP address to the given address to zero.
// This is meant to annotate longjmp and other non-local jumps.
// This function needs to know the (almost) exact destination frame address;
diff --git a/compiler-rt/lib/hwasan/hwasan.cpp b/compiler-rt/lib/hwasan/hwasan.cpp
index 2f6cb10caf1be6..52780becbdb264 100644
--- a/compiler-rt/lib/hwasan/hwasan.cpp
+++ b/compiler-rt/lib/hwasan/hwasan.cpp
@@ -678,6 +678,8 @@ uptr __hwasan_tag_pointer(uptr p, u8 tag) {
return AddTagToPointer(p, tag);
}
+u8 __hwasan_get_tag_from_pointer(uptr p) { return GetTagFromPointer(p); }
+
void __hwasan_handle_longjmp(const void *sp_dst) {
uptr dst = (uptr)sp_dst;
// HWASan does not support tagged SP.
diff --git a/compiler-rt/lib/hwasan/hwasan.h b/compiler-rt/lib/hwasan/hwasan.h
index 37ef4822285110..df21375e81671f 100644
--- a/compiler-rt/lib/hwasan/hwasan.h
+++ b/compiler-rt/lib/hwasan/hwasan.h
@@ -104,9 +104,9 @@ static inline void *UntagPtr(const void *tagged_ptr) {
}
static inline uptr AddTagToPointer(uptr p, tag_t tag) {
- return InTaggableRegion(p)
- ? ((p & ~kAddressTagMask) | ((uptr)tag << kAddressTagShift))
- : p;
+ return InTaggableRegion(p) ? ((p & ~kAddressTagMask) |
+ ((uptr)(tag & kTagMask) << kAddressTagShift))
+ : p;
}
namespace __hwasan {
diff --git a/compiler-rt/lib/hwasan/hwasan_interface_internal.h b/compiler-rt/lib/hwasan/hwasan_interface_internal.h
index e7804cc4903343..8f2f77dad917d2 100644
--- a/compiler-rt/lib/hwasan/hwasan_interface_internal.h
+++ b/compiler-rt/lib/hwasan/hwasan_interface_internal.h
@@ -160,6 +160,9 @@ void __hwasan_tag_memory(uptr p, u8 tag, uptr sz);
SANITIZER_INTERFACE_ATTRIBUTE
uptr __hwasan_tag_pointer(uptr p, u8 tag);
+SANITIZER_INTERFACE_ATTRIBUTE
+u8 __hwasan_get_tag_from_pointer(uptr p);
+
SANITIZER_INTERFACE_ATTRIBUTE
void __hwasan_tag_mismatch(uptr addr, u8 ts);
diff --git a/compiler-rt/lib/lsan/lsan.cpp b/compiler-rt/lib/lsan/lsan.cpp
index 6b223603c6a79c..7a27b600f203f7 100644
--- a/compiler-rt/lib/lsan/lsan.cpp
+++ b/compiler-rt/lib/lsan/lsan.cpp
@@ -101,6 +101,7 @@ extern "C" void __lsan_init() {
InstallDeadlySignalHandlers(LsanOnDeadlySignal);
InitializeMainThread();
InstallAtExitCheckLeaks();
+ InstallAtForkHandler();
InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir);
diff --git a/compiler-rt/lib/lsan/lsan.h b/compiler-rt/lib/lsan/lsan.h
index 757edec8e104f9..0074ad5308785c 100644
--- a/compiler-rt/lib/lsan/lsan.h
+++ b/compiler-rt/lib/lsan/lsan.h
@@ -40,6 +40,7 @@ void InitializeInterceptors();
void ReplaceSystemMalloc();
void LsanOnDeadlySignal(int signo, void *siginfo, void *context);
void InstallAtExitCheckLeaks();
+void InstallAtForkHandler();
#define ENSURE_LSAN_INITED \
do { \
diff --git a/compiler-rt/lib/lsan/lsan_common.cpp b/compiler-rt/lib/lsan/lsan_common.cpp
index 8b1af5b629fbce..e24839c984b346 100644
--- a/compiler-rt/lib/lsan/lsan_common.cpp
+++ b/compiler-rt/lib/lsan/lsan_common.cpp
@@ -42,6 +42,9 @@ namespace __lsan {
// also to protect the global list of root regions.
static Mutex global_mutex;
+void LockGlobal() SANITIZER_ACQUIRE(global_mutex) { global_mutex.Lock(); }
+void UnlockGlobal() SANITIZER_RELEASE(global_mutex) { global_mutex.Unlock(); }
+
Flags lsan_flags;
void DisableCounterUnderflow() {
diff --git a/compiler-rt/lib/lsan/lsan_common.h b/compiler-rt/lib/lsan/lsan_common.h
index d3e768363e93b9..c598b62105873e 100644
--- a/compiler-rt/lib/lsan/lsan_common.h
+++ b/compiler-rt/lib/lsan/lsan_common.h
@@ -120,6 +120,10 @@ void GetRunningThreadsLocked(InternalMmapVector<tid_t> *threads);
void LockAllocator();
void UnlockAllocator();
+// Lock/unlock global mutext.
+void LockGlobal();
+void UnlockGlobal();
+
// Returns the address range occupied by the global allocator object.
void GetAllocatorGlobalRange(uptr *begin, uptr *end);
// If p points into a chunk that has been allocated to the user, returns its
diff --git a/compiler-rt/lib/lsan/lsan_fuchsia.cpp b/compiler-rt/lib/lsan/lsan_fuchsia.cpp
index 4edac9757a9c49..ba59bc9b71e332 100644
--- a/compiler-rt/lib/lsan/lsan_fuchsia.cpp
+++ b/compiler-rt/lib/lsan/lsan_fuchsia.cpp
@@ -80,6 +80,7 @@ void GetAllThreadAllocatorCachesLocked(InternalMmapVector<uptr> *caches) {
// On Fuchsia, leak detection is done by a special hook after atexit hooks.
// So this doesn't install any atexit hook like on other platforms.
void InstallAtExitCheckLeaks() {}
+void InstallAtForkHandler() {}
// ASan defines this to check its `halt_on_error` flag.
bool UseExitcodeOnLeak() { return true; }
diff --git a/compiler-rt/lib/lsan/lsan_posix.cpp b/compiler-rt/lib/lsan/lsan_posix.cpp
index 732b8af2096701..3677f0141a2f02 100644
--- a/compiler-rt/lib/lsan/lsan_posix.cpp
+++ b/compiler-rt/lib/lsan/lsan_posix.cpp
@@ -14,6 +14,8 @@
#include "sanitizer_common/sanitizer_platform.h"
#if SANITIZER_POSIX
+# include <pthread.h>
+
# include "lsan.h"
# include "lsan_allocator.h"
# include "lsan_thread.h"
@@ -98,6 +100,22 @@ void InstallAtExitCheckLeaks() {
Atexit(DoLeakCheck);
}
+void InstallAtForkHandler() {
+ auto before = []() {
+ LockGlobal();
+ LockThreads();
+ LockAllocator();
+ StackDepotLockAll();
+ };
+ auto after = []() {
+ StackDepotUnlockAll();
+ UnlockAllocator();
+ UnlockThreads();
+ UnlockGlobal();
+ };
+ pthread_atfork(before, after, after);
+}
+
} // namespace __lsan
#endif // SANITIZER_POSIX
diff --git a/compiler-rt/test/hwasan/TestCases/tag-ptr.cpp b/compiler-rt/test/hwasan/TestCases/tag-ptr.cpp
new file mode 100644
index 00000000000000..2f00e7913bb155
--- /dev/null
+++ b/compiler-rt/test/hwasan/TestCases/tag-ptr.cpp
@@ -0,0 +1,24 @@
+// RUN: %clangxx_hwasan -O0 %s -o %t && %run %t
+
+#include <assert.h>
+#include <memory>
+#include <sanitizer/hwasan_interface.h>
+#include <set>
+#include <stdio.h>
+
+int main() {
+ auto p = std::make_unique<char>();
+ std::set<void *> ptrs;
+ for (unsigned i = 0;; ++i) {
+ void *ptr = __hwasan_tag_pointer(p.get(), i);
+ if (!ptrs.insert(ptr).second)
+ break;
+ fprintf(stderr, "%p, %u, %u\n", ptr, i, __hwasan_get_tag_from_pointer(ptr));
+ assert(__hwasan_get_tag_from_pointer(ptr) == i);
+ }
+#ifdef __x86_64__
+ assert(ptrs.size() == 8);
+#else
+ assert(ptrs.size() == 256);
+#endif
+}
diff --git a/compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.c b/compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.c
index cbdf9ee00cff5e..67d2993d11bf8f 100644
--- a/compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.c
+++ b/compiler-rt/test/sanitizer_common/TestCases/Posix/fork_threaded.c
@@ -1,6 +1,6 @@
// RUN: %clang -O0 %s -o %t && %env_tool_opts=die_after_fork=0 %run %t
-// UNSUPPORTED: asan, lsan, hwasan
+// UNSUPPORTED: asan, hwasan
// Forking in multithread environment is unsupported. However we already have
// some workarounds, and will add more, so this is the test.
diff --git a/compiler-rt/test/sanitizer_common/sanitizer_specific.h b/compiler-rt/test/sanitizer_common/sanitizer_specific.h
index 898899f00e3701..541af18a74979b 100644
--- a/compiler-rt/test/sanitizer_common/sanitizer_specific.h
+++ b/compiler-rt/test/sanitizer_common/sanitizer_specific.h
@@ -31,6 +31,19 @@ static void make_mem_good(void *p, size_t s) {
static void make_mem_bad(void *p, size_t s) {
__asan_poison_memory_region(p, s);
}
+#elif __has_feature(hwaddress_sanitizer)
+# include <sanitizer/hwasan_interface.h>
+# include <stdlib.h>
+static void check_mem_is_good(void *p, size_t s) {
+ if (__hwasan_test_shadow(p, s) != -1)
+ abort();
+}
+static void make_mem_good(void *p, size_t s) {
+ __hwasan_tag_memory(p, __hwasan_get_tag_from_pointer(p), s);
+}
+static void make_mem_bad(void *p, size_t s) {
+ __hwasan_tag_memory(p, ~__hwasan_get_tag_from_pointer(p), s);
+}
#else
static void check_mem_is_good(void *p, size_t s) {}
static void make_mem_good(void *p, size_t s) {}
More information about the libcxx-commits
mailing list