[PATCH] D60981: [TSan] Improve handling of stack pointer mangling in {set,long}jmp, pt.1

Julian Lettner via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Fri Jun 28 10:27:44 PDT 2019


This revision was automatically updated to reflect the committed changes.
Closed by commit rL364662: [TSan] Improve handling of stack pointer mangling in {set,long}jmp, pt.1 (authored by yln, committed by ).
Herald added a subscriber: delcypher.

Changed prior to commit:
  https://reviews.llvm.org/D60981?vs=196136&id=207093#toc

Repository:
  rL LLVM

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D60981/new/

https://reviews.llvm.org/D60981

Files:
  compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
  compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h
  compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc
  compiler-rt/trunk/lib/tsan/rtl/tsan_platform_mac.cc


Index: compiler-rt/trunk/lib/tsan/rtl/tsan_platform_mac.cc
===================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_platform_mac.cc
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_platform_mac.cc
@@ -259,6 +259,10 @@
   }
 }
 
+uptr UnmangleLongJmpSp(uptr mangled_sp) {
+  return mangled_sp ^ __tsan_darwin_setjmp_xor_key;
+}
+
 #if !SANITIZER_GO
 void ImitateTlsWrite(ThreadState *thr, uptr tls_addr, uptr tls_size) {
   // The pointer to the ThreadState object is stored in the shadow memory
Index: compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc
===================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_platform_linux.cc
@@ -69,6 +69,7 @@
 
 #if SANITIZER_LINUX && defined(__aarch64__)
 void InitializeGuardPtr() __attribute__((visibility("hidden")));
+extern "C" uptr _tsan_pointer_chk_guard;
 #endif
 
 namespace __tsan {
@@ -334,6 +335,38 @@
   return res;
 }
 
+// Reverse operation of libc stack pointer mangling
+uptr UnmangleLongJmpSp(uptr mangled_sp) {
+#if defined(__x86_64__)
+#if SANITIZER_FREEBSD || SANITIZER_NETBSD
+  return mangled_sp;
+#else  // Linux
+  // Reverse of:
+  //   xor  %fs:0x30, %rsi
+  //   rol  $0x11, %rsi
+  uptr sp;
+  asm("ror  $0x11,     %0 \n"
+      "xor  %%fs:0x30, %0 \n"
+      : "=r" (sp)
+      : "0" (mangled_sp));
+  return sp;
+#endif
+#elif defined(__aarch64__)
+  return mangled_sp ^ _tsan_pointer_chk_guard;
+#elif defined(__powerpc64__)
+  // Reverse of:
+  //  ld   r4, -28696(r13)
+  //  xor  r4, r3, r4
+  uptr xor_guard;
+  asm("ld  %0, -28696(%%r13) \n" : "=r" (xor_guard));
+  return mangled_sp ^ xor_guard;
+#elif defined(__mips__)
+  return mangled_sp;
+#else
+  #error "Unknown platform"
+#endif
+}
+
 void ImitateTlsWrite(ThreadState *thr, uptr tls_addr, uptr tls_size) {
   // Check that the thr object is in tls;
   const uptr thr_beg = (uptr)thr;
Index: compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
===================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
@@ -528,10 +528,13 @@
   uptr mangled_sp = env[6];
 # endif
 #endif
+  uptr sp = UnmangleLongJmpSp(mangled_sp);
   // Find the saved buf by mangled_sp.
   for (uptr i = 0; i < thr->jmp_bufs.Size(); i++) {
     JmpBuf *buf = &thr->jmp_bufs[i];
     if (buf->mangled_sp == mangled_sp) {
+      CHECK_EQ(buf->sp, sp);
+      // TODO(yln): Lookup via sp, remove mangled_sp from struct.
       CHECK_GE(thr->shadow_stack_pos, buf->shadow_stack_pos);
       // Unwind the stack.
       while (thr->shadow_stack_pos > buf->shadow_stack_pos)
Index: compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h
===================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_platform.h
@@ -1011,6 +1011,7 @@
 void WriteMemoryProfile(char *buf, uptr buf_size, uptr nthread, uptr nlive);
 int ExtractResolvFDs(void *state, int *fds, int nfd);
 int ExtractRecvmsgFDs(void *msg, int *fds, int nfd);
+uptr UnmangleLongJmpSp(uptr mangled_sp);
 void ImitateTlsWrite(ThreadState *thr, uptr tls_addr, uptr tls_size);
 
 int call_pthread_cancel_with_cleanup(int(*fn)(void *c, void *m,


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D60981.207093.patch
Type: text/x-patch
Size: 3358 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190628/77ff58fb/attachment.bin>


More information about the llvm-commits mailing list