diff options
Diffstat (limited to 'lib/hwasan')
-rw-r--r-- | lib/hwasan/hwasan.cpp | 2 | ||||
-rw-r--r-- | lib/hwasan/hwasan.h | 1 | ||||
-rw-r--r-- | lib/hwasan/hwasan_linux.cpp | 39 |
3 files changed, 42 insertions, 0 deletions
diff --git a/lib/hwasan/hwasan.cpp b/lib/hwasan/hwasan.cpp index 3a5b8791a..7b5c6c694 100644 --- a/lib/hwasan/hwasan.cpp +++ b/lib/hwasan/hwasan.cpp @@ -312,6 +312,8 @@ static void InitLoadedGlobals() { static void InitInstrumentation() { if (hwasan_instrumentation_inited) return; + InitPrctl(); + if (!InitShadow()) { Printf("FATAL: HWAddressSanitizer cannot mmap the shadow memory.\n"); DumpProcessMap(); diff --git a/lib/hwasan/hwasan.h b/lib/hwasan/hwasan.h index 817cee650..9e0ced93b 100644 --- a/lib/hwasan/hwasan.h +++ b/lib/hwasan/hwasan.h @@ -74,6 +74,7 @@ extern int hwasan_report_count; bool ProtectRange(uptr beg, uptr end); bool InitShadow(); +void InitPrctl(); void InitThreads(); void MadviseShadow(); char *GetProcSelfMaps(); diff --git a/lib/hwasan/hwasan_linux.cpp b/lib/hwasan/hwasan_linux.cpp index 051ec2fb9..948e40154 100644 --- a/lib/hwasan/hwasan_linux.cpp +++ b/lib/hwasan/hwasan_linux.cpp @@ -34,6 +34,8 @@ #include <sys/time.h> #include <unistd.h> #include <unwind.h> +#include <sys/prctl.h> +#include <errno.h> #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_procmaps.h" @@ -144,6 +146,43 @@ static void InitializeShadowBaseAddress(uptr shadow_size_bytes) { FindDynamicShadowStart(shadow_size_bytes); } +void InitPrctl() { +#define PR_SET_TAGGED_ADDR_CTRL 55 +#define PR_GET_TAGGED_ADDR_CTRL 56 +#define PR_TAGGED_ADDR_ENABLE (1UL << 0) + // Check we're running on a kernel that can use the tagged address ABI. + if (internal_prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0) == (uptr)-1 && + errno == EINVAL) { +#if SANITIZER_ANDROID + // Some older Android kernels have the tagged pointer ABI on + // unconditionally, and hence don't have the tagged-addr prctl while still + // allow the ABI. + // If targeting Android and the prctl is not around we assume this is the + // case. + return; +#else + Printf( + "FATAL: " + "HWAddressSanitizer requires a kernel with tagged address ABI.\n"); + Die(); +#endif + } + + // Turn on the tagged address ABI. + if (internal_prctl(PR_SET_TAGGED_ADDR_CTRL, PR_TAGGED_ADDR_ENABLE, 0, 0, 0) == + (uptr)-1 || + !internal_prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0)) { + Printf( + "FATAL: HWAddressSanitizer failed to enable tagged address syscall " + "ABI.\nSuggest check `sysctl abi.tagged_addr_disabled` " + "configuration.\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(); |