[compiler-rt] r352816 - hwasan: Add __hwasan_init_static() function.

Peter Collingbourne via llvm-commits llvm-commits at lists.llvm.org
Thu Jan 31 15:37:12 PST 2019


Author: pcc
Date: Thu Jan 31 15:37:12 2019
New Revision: 352816

URL: http://llvm.org/viewvc/llvm-project?rev=352816&view=rev
Log:
hwasan: Add __hwasan_init_static() function.

This function initializes enough of the runtime to be able to run
instrumented code in a statically linked executable. It replaces
__hwasan_shadow_init() which wasn't doing enough initialization for
instrumented code that uses either TLS or IFUNC to work.

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

Modified:
    compiler-rt/trunk/include/sanitizer/hwasan_interface.h
    compiler-rt/trunk/lib/hwasan/hwasan.cc
    compiler-rt/trunk/lib/hwasan/hwasan.h
    compiler-rt/trunk/lib/hwasan/hwasan_dynamic_shadow.cc
    compiler-rt/trunk/lib/hwasan/hwasan_dynamic_shadow.h
    compiler-rt/trunk/lib/hwasan/hwasan_interface_internal.h
    compiler-rt/trunk/lib/hwasan/hwasan_linux.cc
    compiler-rt/trunk/lib/hwasan/hwasan_thread.cc
    compiler-rt/trunk/lib/hwasan/hwasan_thread.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=352816&r1=352815&r2=352816&view=diff
==============================================================================
--- compiler-rt/trunk/include/sanitizer/hwasan_interface.h (original)
+++ compiler-rt/trunk/include/sanitizer/hwasan_interface.h Thu Jan 31 15:37:12 2019
@@ -18,11 +18,15 @@
 #ifdef __cplusplus
 extern "C" {
 #endif
-  // Initialize shadow but not the rest of the runtime.
+  // Libc hook for program startup in statically linked executables.
+  // Initializes enough of the runtime to run instrumented code. This function
+  // should only be called in statically linked executables because it modifies
+  // the GOT, which won't work in regular binaries because RELRO will already
+  // have been applied by the time the function is called. This also means that
+  // the function should be called before libc applies RELRO.
   // Does not call libc unless there is an error.
-  // Can be called multiple times, or not at all (in which case shadow will
-  // be initialized in compiler-inserted __hwasan_init() call).
-  void __hwasan_shadow_init(void);
+  // Can be called multiple times.
+  void __hwasan_init_static(void);
 
   // This function may be optionally provided by user and should return
   // a string containing HWASan runtime options. See asan_flags.h for details.

Modified: compiler-rt/trunk/lib/hwasan/hwasan.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan.cc?rev=352816&r1=352815&r2=352816&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan.cc (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan.cc Thu Jan 31 15:37:12 2019
@@ -13,6 +13,7 @@
 
 #include "hwasan.h"
 #include "hwasan_checks.h"
+#include "hwasan_dynamic_shadow.h"
 #include "hwasan_poisoning.h"
 #include "hwasan_report.h"
 #include "hwasan_thread.h"
@@ -57,7 +58,7 @@ Flags *flags() {
 }
 
 int hwasan_inited = 0;
-int hwasan_shadow_inited = 0;
+int hwasan_instrumentation_inited = 0;
 bool hwasan_init_is_running;
 
 int hwasan_report_count = 0;
@@ -246,28 +247,39 @@ const char *GetStackFrameDescr(uptr pc)
   return nullptr;
 }
 
-} // namespace __hwasan
-
-// Interface.
-
-using namespace __hwasan;
-
-uptr __hwasan_shadow_memory_dynamic_address;  // Global interface symbol.
+// Prepare to run instrumented code on the main thread.
+void InitInstrumentation() {
+  if (hwasan_instrumentation_inited) return;
 
-void __hwasan_shadow_init() {
-  if (hwasan_shadow_inited) return;
   if (!InitShadow()) {
     Printf("FATAL: HWAddressSanitizer cannot mmap the shadow memory.\n");
     DumpProcessMap();
     Die();
   }
-  hwasan_shadow_inited = 1;
+
+  InitThreads();
+  hwasanThreadList().CreateCurrentThread();
+
+  hwasan_instrumentation_inited = 1;
 }
 
+} // namespace __hwasan
+
+// Interface.
+
+using namespace __hwasan;
+
+uptr __hwasan_shadow_memory_dynamic_address;  // Global interface symbol.
+
 void __hwasan_init_frames(uptr beg, uptr end) {
   InitFrameDescriptors(beg, end);
 }
 
+void __hwasan_init_static() {
+  InitShadowGOT();
+  InitInstrumentation();
+}
+
 void __hwasan_init() {
   CHECK(!hwasan_init_is_running);
   if (hwasan_inited) return;
@@ -288,10 +300,11 @@ void __hwasan_init() {
 
   DisableCoreDumperIfNecessary();
 
-  __hwasan_shadow_init();
+  InitInstrumentation();
 
-  InitThreads();
-  hwasanThreadList().CreateCurrentThread();
+  // Needs to be called here because flags()->random_tags might not have been
+  // initialized when InitInstrumentation() was called.
+  GetCurrentThread()->InitRandomState();
 
   MadviseShadow();
 

Modified: compiler-rt/trunk/lib/hwasan/hwasan.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan.h?rev=352816&r1=352815&r2=352816&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan.h (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan.h Thu Jan 31 15:37:12 2019
@@ -70,6 +70,7 @@ extern int hwasan_report_count;
 bool ProtectRange(uptr beg, uptr end);
 bool InitShadow();
 void InitThreads();
+void InitInstrumentation();
 void MadviseShadow();
 char *GetProcSelfMaps();
 void InitializeInterceptors();

Modified: compiler-rt/trunk/lib/hwasan/hwasan_dynamic_shadow.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_dynamic_shadow.cc?rev=352816&r1=352815&r2=352816&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_dynamic_shadow.cc (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_dynamic_shadow.cc Thu Jan 31 15:37:12 2019
@@ -18,6 +18,9 @@
 #include "sanitizer_common/sanitizer_common.h"
 #include "sanitizer_common/sanitizer_posix.h"
 
+#include <elf.h>
+#include <link.h>
+
 // The code in this file needs to run in an unrelocated binary. It should not
 // access any external symbol, including its own non-hidden globals.
 
@@ -118,10 +121,28 @@ decltype(__hwasan_shadow)* __hwasan_prem
 INTERFACE_ATTRIBUTE __attribute__((ifunc("__hwasan_premap_shadow")))
 void __hwasan_shadow();
 
+extern __attribute((visibility("hidden"))) ElfW(Rela) __rela_iplt_start[],
+    __rela_iplt_end[];
+
 }  // extern "C"
 
 namespace __hwasan {
 
+void InitShadowGOT() {
+  // Call the ifunc resolver for __hwasan_shadow and fill in its GOT entry. This
+  // needs to be done before other ifunc resolvers (which are handled by libc)
+  // because a resolver might read __hwasan_shadow.
+  typedef ElfW(Addr) (*ifunc_resolver_t)(void);
+  for (ElfW(Rela) *r = __rela_iplt_start; r != __rela_iplt_end; ++r) {
+    ElfW(Addr)* offset = reinterpret_cast<ElfW(Addr)*>(r->r_offset);
+    ElfW(Addr) resolver = r->r_addend;
+    if (resolver == reinterpret_cast<ElfW(Addr)>(&__hwasan_premap_shadow)) {
+      *offset = reinterpret_cast<ifunc_resolver_t>(resolver)();
+      break;
+    }
+  }
+}
+
 uptr FindDynamicShadowStart(uptr shadow_size_bytes) {
   if (IsPremapShadowAvailable())
     return FindPremappedShadowStart(shadow_size_bytes);
@@ -132,10 +153,12 @@ uptr FindDynamicShadowStart(uptr shadow_
 #else
 namespace __hwasan {
 
+void InitShadowGOT() {}
+
 uptr FindDynamicShadowStart(uptr shadow_size_bytes) {
   return MapDynamicShadow(shadow_size_bytes);
 }
 
 }  // namespace __hwasan
-#
+
 #endif  // SANITIZER_ANDROID

Modified: compiler-rt/trunk/lib/hwasan/hwasan_dynamic_shadow.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_dynamic_shadow.h?rev=352816&r1=352815&r2=352816&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_dynamic_shadow.h (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_dynamic_shadow.h Thu Jan 31 15:37:12 2019
@@ -20,6 +20,7 @@
 namespace __hwasan {
 
 uptr FindDynamicShadowStart(uptr shadow_size_bytes);
+void InitShadowGOT();
 
 }  // namespace __hwasan
 

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=352816&r1=352815&r2=352816&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_interface_internal.h (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_interface_internal.h Thu Jan 31 15:37:12 2019
@@ -20,7 +20,7 @@
 extern "C" {
 
 SANITIZER_INTERFACE_ATTRIBUTE
-void __hwasan_shadow_init();
+void __hwasan_init_static();
 
 SANITIZER_INTERFACE_ATTRIBUTE
 void __hwasan_init();

Modified: compiler-rt/trunk/lib/hwasan/hwasan_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_linux.cc?rev=352816&r1=352815&r2=352816&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_linux.cc (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_linux.cc Thu Jan 31 15:37:12 2019
@@ -236,7 +236,7 @@ void InstallAtExitHandler() {
 // ---------------------- TSD ---------------- {{{1
 
 extern "C" void __hwasan_thread_enter() {
-  hwasanThreadList().CreateCurrentThread();
+  hwasanThreadList().CreateCurrentThread()->InitRandomState();
 }
 
 extern "C" void __hwasan_thread_exit() {
@@ -289,7 +289,9 @@ uptr *GetCurrentThreadLongPtr() {
 #if SANITIZER_ANDROID
 void AndroidTestTlsSlot() {
   uptr kMagicValue = 0x010203040A0B0C0D;
-  *(uptr *)get_android_tls_ptr() = kMagicValue;
+  uptr *tls_ptr = GetCurrentThreadLongPtr();
+  uptr old_value = *tls_ptr;
+  *tls_ptr = kMagicValue;
   dlerror();
   if (*(uptr *)get_android_tls_ptr() != kMagicValue) {
     Printf(
@@ -297,6 +299,7 @@ void AndroidTestTlsSlot() {
         "for dlerror().\n");
     Die();
   }
+  *tls_ptr = old_value;
 }
 #else
 void AndroidTestTlsSlot() {}

Modified: compiler-rt/trunk/lib/hwasan/hwasan_thread.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_thread.cc?rev=352816&r1=352815&r2=352816&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_thread.cc (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_thread.cc Thu Jan 31 15:37:12 2019
@@ -25,10 +25,13 @@ static u32 RandomSeed() {
   return seed;
 }
 
+void Thread::InitRandomState() {
+  random_state_ = flags()->random_tags ? RandomSeed() : unique_id_;
+}
+
 void Thread::Init(uptr stack_buffer_start, uptr stack_buffer_size) {
   static u64 unique_id;
   unique_id_ = unique_id++;
-  random_state_ = flags()->random_tags ? RandomSeed() : unique_id_;
   if (auto sz = flags()->heap_history_size)
     heap_allocations_ = HeapAllocationsRingBuffer::New(sz);
 

Modified: compiler-rt/trunk/lib/hwasan/hwasan_thread.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_thread.h?rev=352816&r1=352815&r2=352816&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_thread.h (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_thread.h Thu Jan 31 15:37:12 2019
@@ -24,6 +24,7 @@ typedef __sanitizer::CompactRingBuffer<u
 class Thread {
  public:
   void Init(uptr stack_buffer_start, uptr stack_buffer_size);  // Must be called from the thread itself.
+  void InitRandomState();
   void Destroy();
 
   uptr stack_top() { return stack_top_; }




More information about the llvm-commits mailing list