[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