diff --git a/compiler-rt/lib/hwasan/hwasan.h b/compiler-rt/lib/hwasan/hwasan.h --- a/compiler-rt/lib/hwasan/hwasan.h +++ b/compiler-rt/lib/hwasan/hwasan.h @@ -74,6 +74,7 @@ bool ProtectRange(uptr beg, uptr end); bool InitShadow(); +void InitPrctl(); void InitThreads(); void MadviseShadow(); char *GetProcSelfMaps(); diff --git a/compiler-rt/lib/hwasan/hwasan.cpp b/compiler-rt/lib/hwasan/hwasan.cpp --- a/compiler-rt/lib/hwasan/hwasan.cpp +++ b/compiler-rt/lib/hwasan/hwasan.cpp @@ -354,6 +354,8 @@ hwasan_init_is_running = 1; SanitizerToolName = "HWAddressSanitizer"; + InitPrctl(); + InitTlsSize(); CacheBinaryName(); diff --git a/compiler-rt/lib/hwasan/hwasan_linux.cpp b/compiler-rt/lib/hwasan/hwasan_linux.cpp --- a/compiler-rt/lib/hwasan/hwasan_linux.cpp +++ b/compiler-rt/lib/hwasan/hwasan_linux.cpp @@ -34,6 +34,7 @@ #include #include #include +#include #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_procmaps.h" @@ -144,6 +145,33 @@ FindDynamicShadowStart(shadow_size_bytes); } +void InitPrctl() { + // This function uses the prctl interface to ask the kernel to accept + // tagged pointers. + // + // Here we unconditionally request that the PR_TAGGED_ADDR_ENABLE value is + // turned on, there is nothing else that can be done. +#define PR_SET_TAGGED_ADDR_CTRL 55 +#define PR_GET_TAGGED_ADDR_CTRL 56 +#define PR_TAGGED_ADDR_ENABLE (1UL << 0) + if (prctl(PR_SET_TAGGED_ADDR_CTRL, PR_TAGGED_ADDR_ENABLE, 0, 0, 0) == -1 + || ! prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0)) { +#if SANITIZER_ANDROID + // Some older Android kernels have the tagged pointer ABI on + // unconditionally, and hence don't have the tagged-addr prctl. + // + // In order to handle those we ignore getting EINVAL. */ + if (errno == EINVAL) + return; +#endif + Printf("FATAL: HWAddressSanitizer failed to enable tagged pointer syscall ABI.\n"); + Die(); + } +#undef PR_SET_TAGGED_ADDR_CTRL +#undef PR_GET_TAGGED_ADDR_CTRL +#undef PR_TAGGED_ADDR_ENABLE +} + bool InitShadow() { // Define the entire memory range. kHighMemEnd = GetHighMemEnd();