Skip to content

Commit 92a8708

Browse files
authored
[compiler-rt] Map internal_sigaction to __sys_sigaction on FreeBSD (#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.
1 parent 19bbbcb commit 92a8708

File tree

1 file changed

+14
-2
lines changed

1 file changed

+14
-2
lines changed

compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@
5454
# undef MAP_NORESERVE
5555
# define MAP_NORESERVE 0
5656
extern const Elf_Auxinfo *__elf_aux_vector;
57+
extern "C" int __sys_sigaction(int signum, const struct sigaction *act,
58+
struct sigaction *oldact);
5759
# endif
5860

5961
# if SANITIZER_NETBSD
@@ -93,12 +95,22 @@ SANITIZER_WEAK_ATTRIBUTE int real_sigaction(int signum, const void *act,
9395
void *oldact);
9496

9597
int internal_sigaction(int signum, const void *act, void *oldact) {
96-
# if !SANITIZER_GO
98+
# if SANITIZER_FREEBSD
99+
// On FreeBSD, call the sigaction syscall directly (part of libsys in FreeBSD
100+
// 15) since the libc version goes via a global interposing table. Due to
101+
// library initialization order the table can be relocated after the call to
102+
// InitializeDeadlySignals() which then crashes when dereferencing the
103+
// uninitialized pointer in libc.
104+
return __sys_sigaction(signum, (const struct sigaction *)act,
105+
(struct sigaction *)oldact);
106+
# else
107+
# if !SANITIZER_GO
97108
if (&real_sigaction)
98109
return real_sigaction(signum, act, oldact);
99-
# endif
110+
# endif
100111
return sigaction(signum, (const struct sigaction *)act,
101112
(struct sigaction *)oldact);
113+
# endif
102114
}
103115

104116
void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,

0 commit comments

Comments
 (0)