[compiler-rt] r375166 - libhwasan initialisation include kernel syscall ABI relaxation

Evgeniy Stepanov via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 17 13:32:54 PDT 2019


Author: eugenis
Date: Thu Oct 17 13:32:54 2019
New Revision: 375166

URL: http://llvm.org/viewvc/llvm-project?rev=375166&view=rev
Log:
libhwasan initialisation include kernel syscall ABI relaxation

Summary:
Until now AArch64 development has been on patched kernels that have an always
on relaxed syscall ABI where tagged pointers are accepted.
The patches that have gone into the mainline kernel rely on each process opting
in to this relaxed ABI.

This commit adds code to choose that ABI into __hwasan_init.

The idea has already been agreed with one of the hwasan developers
(http://lists.llvm.org/pipermail/llvm-dev/2019-September/135328.html).

The patch ignores failures of `EINVAL` for Android, since there are older versions of the Android kernel that don't require this `prctl` or even have the relevant values.  Avoiding EINVAL will let the library run on them.

I've tested this on an AArch64 VM running a kernel that requires this
prctl, having compiled both with clang and gcc.

Patch by Matthew Malcomson.

Reviewers: eugenis, kcc, pcc

Reviewed By: eugenis

Subscribers: srhines, kristof.beyls, #sanitizers, llvm-commits

Tags: #sanitizers, #llvm

Differential Revision: https://reviews.llvm.org/D68794

Modified:
    compiler-rt/trunk/lib/hwasan/hwasan.cpp
    compiler-rt/trunk/lib/hwasan/hwasan.h
    compiler-rt/trunk/lib/hwasan/hwasan_linux.cpp

Modified: compiler-rt/trunk/lib/hwasan/hwasan.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan.cpp?rev=375166&r1=375165&r2=375166&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan.cpp (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan.cpp Thu Oct 17 13:32:54 2019
@@ -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();

Modified: compiler-rt/trunk/lib/hwasan/hwasan.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan.h?rev=375166&r1=375165&r2=375166&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan.h (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan.h Thu Oct 17 13:32:54 2019
@@ -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();

Modified: compiler-rt/trunk/lib/hwasan/hwasan_linux.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_linux.cpp?rev=375166&r1=375165&r2=375166&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_linux.cpp (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_linux.cpp Thu Oct 17 13:32:54 2019
@@ -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(
       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();




More information about the llvm-commits mailing list