[compiler-rt] r339963 - Revert "Revert "[hwasan] Add __hwasan_handle_longjmp.""

Evgeniy Stepanov via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 16 16:17:14 PDT 2018


Author: eugenis
Date: Thu Aug 16 16:17:14 2018
New Revision: 339963

URL: http://llvm.org/viewvc/llvm-project?rev=339963&view=rev
Log:
Revert "Revert "[hwasan] Add __hwasan_handle_longjmp.""

This reapplies commit r339935 with the following changes:
* make longjmp test C, not C++, to avoid dependency on libc++/libstdc++
* untag pointer in memset interceptor

x86_64 does not have TBI, so hwasan barely works there. Tests must be carefully
written in a way that does not leak tagged pointer to system libraries.

Added:
    compiler-rt/trunk/test/hwasan/TestCases/longjmp.c
Modified:
    compiler-rt/trunk/include/sanitizer/hwasan_interface.h
    compiler-rt/trunk/lib/hwasan/hwasan.cc
    compiler-rt/trunk/lib/hwasan/hwasan_interceptors.cc
    compiler-rt/trunk/lib/hwasan/hwasan_interface_internal.h

Modified: compiler-rt/trunk/include/sanitizer/hwasan_interface.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/include/sanitizer/hwasan_interface.h?rev=339963&r1=339962&r2=339963&view=diff
==============================================================================
--- compiler-rt/trunk/include/sanitizer/hwasan_interface.h (original)
+++ compiler-rt/trunk/include/sanitizer/hwasan_interface.h Thu Aug 16 16:17:14 2018
@@ -40,6 +40,13 @@ extern "C" {
   /// Set pointer tag. Previous tag is lost.
   void *__hwasan_tag_pointer(const volatile void *p, unsigned char tag);
 
+  // Set memory tag from the current SP address to the given address to zero.
+  // This is meant to annotate longjmp and other non-local jumps.
+  // This function needs to know the (almost) exact destination frame address;
+  // clearing shadow for the entire thread stack like __asan_handle_no_return
+  // does would cause false reports.
+  void __hwasan_handle_longjmp(const void *sp_dst);
+
   // Print shadow and origin for the memory range to stderr in a human-readable
   // format.
   void __hwasan_print_shadow(const volatile void *x, size_t size);

Modified: compiler-rt/trunk/lib/hwasan/hwasan.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan.cc?rev=339963&r1=339962&r2=339963&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan.cc (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan.cc Thu Aug 16 16:17:14 2018
@@ -412,6 +412,24 @@ uptr __hwasan_tag_pointer(uptr p, u8 tag
   return AddTagToPointer(p, tag);
 }
 
+void __hwasan_handle_longjmp(const void *sp_dst) {
+  uptr dst = (uptr)sp_dst;
+  // HWASan does not support tagged SP.
+  CHECK(GetTagFromPointer(dst) == 0);
+
+  uptr sp = (uptr)__builtin_frame_address(0);
+  static const uptr kMaxExpectedCleanupSize = 64 << 20;  // 64M
+  if (dst < sp || dst - sp > kMaxExpectedCleanupSize) {
+    Report(
+        "WARNING: HWASan is ignoring requested __hwasan_handle_longjmp: "
+        "stack top: %p; target %p; distance: %p (%zd)\n"
+        "False positive error reports may follow\n",
+        (void *)sp, (void *)dst, dst - sp);
+    return;
+  }
+  TagMemory(sp, dst - sp, 0);
+}
+
 static const u8 kFallbackTag = 0xBB;
 
 u8 __hwasan_generate_tag() {

Modified: compiler-rt/trunk/lib/hwasan/hwasan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_interceptors.cc?rev=339963&r1=339962&r2=339963&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_interceptors.cc Thu Aug 16 16:17:14 2018
@@ -426,14 +426,27 @@ int OnExit() {
     *begin = *end = 0;                                                         \
   }
 
-#define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, dst, v, size) \
-  {                                                       \
-    COMMON_INTERCEPTOR_ENTER(ctx, memset, dst, v, size);  \
-    if (common_flags()->intercept_intrin &&               \
-        MEM_IS_APP(GetAddressFromPointer(dst)))           \
-      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size);     \
-    return REAL(memset)(dst, v, size);                    \
+// AArch64 has TBI and can (and must!) pass the pointer to system memset as-is.
+// Other platforms need to remove the tag.
+#if defined(__aarch64__)
+#define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, dst, v, size)     \
+  {                                                           \
+    COMMON_INTERCEPTOR_ENTER(ctx, memset, dst, v, size);      \
+    if (common_flags()->intercept_intrin &&                   \
+        MEM_IS_APP(GetAddressFromPointer(dst)))               \
+      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size);         \
+    return REAL(memset)(dst, v, size); \
   }
+#else
+#define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, dst, v, size)     \
+  {                                                           \
+    COMMON_INTERCEPTOR_ENTER(ctx, memset, dst, v, size);      \
+    if (common_flags()->intercept_intrin &&                   \
+        MEM_IS_APP(GetAddressFromPointer(dst)))               \
+      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size);         \
+    return REAL(memset)(GetAddressFromPointer(dst), v, size); \
+  }
+#endif
 
 #define COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, length, prot, flags, fd, \
                                      offset)                                   \

Modified: compiler-rt/trunk/lib/hwasan/hwasan_interface_internal.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_interface_internal.h?rev=339963&r1=339962&r2=339963&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_interface_internal.h (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_interface_internal.h Thu Aug 16 16:17:14 2018
@@ -111,6 +111,9 @@ SANITIZER_INTERFACE_ATTRIBUTE
 void __hwasan_print_shadow(const void *x, uptr size);
 
 SANITIZER_INTERFACE_ATTRIBUTE
+void __hwasan_handle_longjmp(const void *sp_dst);
+
+SANITIZER_INTERFACE_ATTRIBUTE
 u16 __sanitizer_unaligned_load16(const uu16 *p);
 
 SANITIZER_INTERFACE_ATTRIBUTE

Added: compiler-rt/trunk/test/hwasan/TestCases/longjmp.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/hwasan/TestCases/longjmp.c?rev=339963&view=auto
==============================================================================
--- compiler-rt/trunk/test/hwasan/TestCases/longjmp.c (added)
+++ compiler-rt/trunk/test/hwasan/TestCases/longjmp.c Thu Aug 16 16:17:14 2018
@@ -0,0 +1,28 @@
+// RUN: %clang_hwasan -O0 -DNEGATIVE %s -o %t && %run %t 2>&1
+// RUN: %clang_hwasan -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s
+
+// REQUIRES: stable-runtime
+
+#include <stdlib.h>
+#include <assert.h>
+#include <sanitizer/hwasan_interface.h>
+
+__attribute__((noinline))
+int f(void *caller_frame) {
+  char z[32] = {};
+  char *volatile p = z;
+  // Tag of local is never zero.
+  assert(__hwasan_tag_pointer(p, 0) != p);
+#ifndef NEGATIVE
+  // This will destroy shadow of "z", and the following load will crash.
+  __hwasan_handle_longjmp(caller_frame);
+#endif
+  return p[0];
+}
+
+int main() {
+  return f(__builtin_frame_address(0));
+  // CHECK: READ of size 8
+  // CHECK: pointer tag
+  // CHECK: memory tag 0x0
+}




More information about the llvm-commits mailing list