summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeniy Stepanov <eugeni.stepanov@gmail.com>2019-10-17 20:32:54 +0000
committerEvgeniy Stepanov <eugeni.stepanov@gmail.com>2019-10-17 20:32:54 +0000
commitd5282dfc410c6af5518b046c3ec02339aaf19950 (patch)
tree1c270d24fafe8d8a0f30c183b21200e9a3836c43
parent2ca8e27bd038673b514c8452d661a413ce0d2123 (diff)
downloadbcm5719-llvm-d5282dfc410c6af5518b046c3ec02339aaf19950.tar.gz
bcm5719-llvm-d5282dfc410c6af5518b046c3ec02339aaf19950.zip
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 llvm-svn: 375166
-rw-r--r--compiler-rt/lib/hwasan/hwasan.cpp2
-rw-r--r--compiler-rt/lib/hwasan/hwasan.h1
-rw-r--r--compiler-rt/lib/hwasan/hwasan_linux.cpp39
3 files changed, 42 insertions, 0 deletions
diff --git a/compiler-rt/lib/hwasan/hwasan.cpp b/compiler-rt/lib/hwasan/hwasan.cpp
index 3a5b8791a22..7b5c6c694be 100644
--- a/compiler-rt/lib/hwasan/hwasan.cpp
+++ b/compiler-rt/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/compiler-rt/lib/hwasan/hwasan.h b/compiler-rt/lib/hwasan/hwasan.h
index 817cee65016..9e0ced93b55 100644
--- a/compiler-rt/lib/hwasan/hwasan.h
+++ b/compiler-rt/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/compiler-rt/lib/hwasan/hwasan_linux.cpp b/compiler-rt/lib/hwasan/hwasan_linux.cpp
index 051ec2fb9cc..948e40154fe 100644
--- a/compiler-rt/lib/hwasan/hwasan_linux.cpp
+++ b/compiler-rt/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();
OpenPOWER on IntegriCloud