[compiler-rt] [compiler-rt] Map internal_sigaction to __sys_sigaction on FreeBSD (PR #84441)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 7 23:37:25 PST 2024
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-compiler-rt-sanitizer
Author: Alexander Richardson (arichardson)
<details>
<summary>Changes</summary>
This function is called during very early startup and which can result
in a crash on FreeBSD. The sigaction() function in libc is indirected
via a table so that it can be interposed by the threading library
rather than calling the syscall directly. In the crash I was observing
this table had not yet been relocated, so we ended up jumping to an
invalid address. To avoid this problem we can call __sys_sigaction,
which calls the syscall directly and in FreeBSD 15 is part of libsys
rather than libc, so does not depend on libc being fully initialized.
---
Full diff: https://github.com/llvm/llvm-project/pull/84441.diff
1 Files Affected:
- (modified) compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp (+14-2)
``````````diff
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
index cccbb4d256df2f..6d05411222d9e8 100644
--- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
@@ -54,6 +54,8 @@
# undef MAP_NORESERVE
# define MAP_NORESERVE 0
extern const Elf_Auxinfo *__elf_aux_vector;
+extern "C" int __sys_sigaction(int signum, const struct sigaction *act,
+ struct sigaction *oldact);
# endif
# if SANITIZER_NETBSD
@@ -93,12 +95,22 @@ SANITIZER_WEAK_ATTRIBUTE int real_sigaction(int signum, const void *act,
void *oldact);
int internal_sigaction(int signum, const void *act, void *oldact) {
-# if !SANITIZER_GO
+# if SANITIZER_FREEBSD
+ // On FreeBSD, call the sigaction syscall directly (part of libsys in FreeBSD
+ // 15) since the libc version goes via a global interposing table. Due to
+ // library initialization order the table can be relocated after the call to
+ // InitializeDeadlySignals() which then crashes when dereferencing the
+ // uninitialized pointer in libc.
+ return __sys_sigaction(signum, (const struct sigaction *)act,
+ (struct sigaction *)oldact);
+# else
+# if !SANITIZER_GO
if (&real_sigaction)
return real_sigaction(signum, act, oldact);
-# endif
+# endif
return sigaction(signum, (const struct sigaction *)act,
(struct sigaction *)oldact);
+# endif
}
void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,
``````````
</details>
https://github.com/llvm/llvm-project/pull/84441
More information about the llvm-commits
mailing list