[compiler-rt] [compiler-rt] Map internal_sigaction to __sys_sigaction on FreeBSD (PR #84441)
Alexander Richardson via llvm-commits
llvm-commits at lists.llvm.org
Thu Mar 7 23:36:57 PST 2024
https://github.com/arichardson created https://github.com/llvm/llvm-project/pull/84441
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.
>From 005b726b8fc4a73821c5725cb83dfd0d289c82ca Mon Sep 17 00:00:00 2001
From: Alex Richardson <alexrichardson at google.com>
Date: Thu, 7 Mar 2024 23:36:30 -0800
Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?=
=?UTF-8?q?l=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6-beta.1
---
.../sanitizer_common/sanitizer_linux_libcdep.cpp | 16 ++++++++++++++--
1 file changed, 14 insertions(+), 2 deletions(-)
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,
More information about the llvm-commits
mailing list