Skip to content

Commit 4fa5031

Browse files
committed
[sanitizer] Add re-execution on FreeBSD when ASLR is detected (#73439)
In the FreeBSD base system, re-executing the main binary when ASLR is detected was implemented in the following commits: * https://cgit.freebsd.org/src/commit/?id=7cafe89f9ce33 * https://cgit.freebsd.org/src/commit/?id=96fe7c8ab0f65 * https://cgit.freebsd.org/src/commit/?id=930a7c2ac67e1 * https://cgit.freebsd.org/src/commit/?id=0a736f0a6aeb0 * https://cgit.freebsd.org/src/commit/?id=4c9a0adad1826 Squash all these to bring them into upstream compiler-rt. When ASLR is detected to be enabled, this first force-disables ASLR for the current process, then calls ReExec(). The ReExec() function gets a FreeBSD specific implementation for finding the path of the executed program, via the ELF auxiliary vector. This is done without calling into the regular elf_aux_info(3) function, as that makes use of several already-intercepted functions.
1 parent f385f6c commit 4fa5031

File tree

2 files changed

+16
-4
lines changed

2 files changed

+16
-4
lines changed

compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2323,9 +2323,12 @@ void CheckASLR() {
23232323
return;
23242324
}
23252325
if ((aslr_status & PROC_ASLR_ACTIVE) != 0) {
2326-
Printf("This sanitizer is not compatible with enabled ASLR "
2327-
"and binaries compiled with PIE\n");
2328-
Die();
2326+
VReport(1, "This sanitizer is not compatible with enabled ASLR "
2327+
"and binaries compiled with PIE\n"
2328+
"ASLR will be disabled and the program re-executed.\n");
2329+
int aslr_ctl = PROC_ASLR_FORCE_DISABLE;
2330+
CHECK_NE(internal_procctl(P_PID, 0, PROC_ASLR_CTL, &aslr_ctl), -1);
2331+
ReExec();
23292332
}
23302333
# elif SANITIZER_PPC64V2
23312334
// Disable ASLR for Linux PPC64LE.

compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,12 +48,14 @@
4848
#if SANITIZER_FREEBSD
4949
#include <pthread_np.h>
5050
#include <osreldate.h>
51+
#include <sys/auxv.h>
5152
#include <sys/sysctl.h>
5253
#define pthread_getattr_np pthread_attr_get_np
5354
// The MAP_NORESERVE define has been removed in FreeBSD 11.x, and even before
5455
// that, it was never implemented. So just define it to zero.
5556
#undef MAP_NORESERVE
5657
#define MAP_NORESERVE 0
58+
extern const Elf_Auxinfo *__elf_aux_vector;
5759
#endif
5860

5961
#if SANITIZER_NETBSD
@@ -941,7 +943,14 @@ u64 MonotonicNanoTime() {
941943
void ReExec() {
942944
const char *pathname = "/proc/self/exe";
943945

944-
#if SANITIZER_NETBSD
946+
#if SANITIZER_FREEBSD
947+
for (const auto *aux = __elf_aux_vector; aux->a_type != AT_NULL; aux++) {
948+
if (aux->a_type == AT_EXECPATH) {
949+
pathname = static_cast<const char *>(aux->a_un.a_ptr);
950+
break;
951+
}
952+
}
953+
#elif SANITIZER_NETBSD
945954
static const int name[] = {
946955
CTL_KERN,
947956
KERN_PROC_ARGS,

0 commit comments

Comments
 (0)