[PATCH] D44623: Fix asan on i?86-linux (32-bit) against glibc 2.27 and later

Jakub JelĂ­nek via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon Mar 19 06:47:02 PDT 2018


jakubjelinek created this revision.
jakubjelinek added reviewers: kcc, dvyukov.
jakubjelinek added a project: Sanitizers.
Herald added subscribers: llvm-commits, kubamracek.

Running sanitized 32-bit x86 programs on glibc 2.27 crashes at startup, with:

AddressSanitizer:DEADLYSIGNAL
=============================

50==ERROR: AddressSanitizer: SEGV on unknown address 0xf7a8a250 (pc 0xf7f807f4 bp 0xff969fc8 sp 0xff969f7c T16777215)
---------------------------------------------------------------------------------------------------------------------

50==The signal is caused by a WRITE memory access.
--------------------------------------------------

  #0 0xf7f807f3 in _dl_get_tls_static_info (/lib/ld-linux.so.2+0x127f3)
  #1 0xf7a92599  (/lib/libasan.so.5+0x112599)
  #2 0xf7a80737  (/lib/libasan.so.5+0x100737)
  #3 0xf7f7e14f in _dl_init (/lib/ld-linux.so.2+0x1014f)
  #4 0xf7f6eb49  (/lib/ld-linux.so.2+0xb49)

The problem is that glibc changed the calling convention for the GLIBC_PRIVATE symbol that sanitizer uses (even when it should not, GLIBC_PRIVATE is exactly for symbols that can change at any time, be removed etc.), see https://sourceware.org/ml/libc-alpha/2017-08/msg00497.html


Repository:
  rL LLVM

https://reviews.llvm.org/D44623

Files:
  compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc


Index: compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc
===================================================================
--- compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc
+++ compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc
@@ -173,29 +173,44 @@
 #endif
 }
 
+#ifndef __GLIBC_PREREQ
+#define __GLIBC_PREREQ(x, y) 0
+#endif
+
 #if !SANITIZER_FREEBSD && !SANITIZER_ANDROID && !SANITIZER_GO && \
     !SANITIZER_NETBSD && !SANITIZER_SOLARIS
 static uptr g_tls_size;
 
-#ifdef __i386__
-# define DL_INTERNAL_FUNCTION __attribute__((regparm(3), stdcall))
-#else
-# define DL_INTERNAL_FUNCTION
-#endif
-
 void InitTlsSize() {
 // all current supported platforms have 16 bytes stack alignment
   const size_t kStackAlign = 16;
-  typedef void (*get_tls_func)(size_t*, size_t*) DL_INTERNAL_FUNCTION;
-  get_tls_func get_tls;
-  void *get_tls_static_info_ptr = dlsym(RTLD_NEXT, "_dl_get_tls_static_info");
-  CHECK_EQ(sizeof(get_tls), sizeof(get_tls_static_info_ptr));
-  internal_memcpy(&get_tls, &get_tls_static_info_ptr,
-                  sizeof(get_tls_static_info_ptr));
-  CHECK_NE(get_tls, 0);
   size_t tls_size = 0;
   size_t tls_align = 0;
-  get_tls(&tls_size, &tls_align);
+  void *get_tls_static_info_ptr = dlsym(RTLD_NEXT, "_dl_get_tls_static_info");
+#if defined(__i386__) && !__GLIBC_PREREQ(2, 27)
+  /* On i?86, _dl_get_tls_static_info used to be internal_function, i.e.
+     __attribute__((regparm(3), stdcall)) before glibc 2.27 and is normal
+     function in 2.27 and later.  */
+  if (!dlvsym(RTLD_NEXT, "glob", "GLIBC_2.27")) {
+    typedef void (*get_tls_func)(size_t*, size_t*)
+      __attribute__((regparm(3), stdcall));
+    get_tls_func get_tls;
+    CHECK_EQ(sizeof(get_tls), sizeof(get_tls_static_info_ptr));
+    internal_memcpy(&get_tls, &get_tls_static_info_ptr,
+                    sizeof(get_tls_static_info_ptr));
+    CHECK_NE(get_tls, 0);
+    get_tls(&tls_size, &tls_align);
+  } else
+#endif
+  {
+    typedef void (*get_tls_func)(size_t*, size_t*);
+    get_tls_func get_tls;
+    CHECK_EQ(sizeof(get_tls), sizeof(get_tls_static_info_ptr));
+    internal_memcpy(&get_tls, &get_tls_static_info_ptr,
+                    sizeof(get_tls_static_info_ptr));
+    CHECK_NE(get_tls, 0);
+    get_tls(&tls_size, &tls_align);
+  }
   if (tls_align < kStackAlign)
     tls_align = kStackAlign;
   g_tls_size = RoundUpTo(tls_size, tls_align);


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D44623.138907.patch
Type: text/x-patch
Size: 2407 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180319/b8b3f0ea/attachment.bin>


More information about the llvm-commits mailing list