[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