[PATCH] D47995: [ASAN] fix startup crash in dlsym for long paths since glibc 2.27

Peter Wu via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 14 03:47:36 PDT 2018


This revision was automatically updated to reflect the committed changes.
Closed by commit rL334703: [ASAN] fix startup crash in dlsym for long paths since glibc 2.27 (authored by Lekensteyn, committed by ).
Herald added a subscriber: delcypher.

Changed prior to commit:
  https://reviews.llvm.org/D47995?vs=150661&id=151324#toc

Repository:
  rL LLVM

https://reviews.llvm.org/D47995

Files:
  compiler-rt/trunk/lib/asan/asan_malloc_linux.cc
  compiler-rt/trunk/test/asan/TestCases/long-object-path.cc


Index: compiler-rt/trunk/lib/asan/asan_malloc_linux.cc
===================================================================
--- compiler-rt/trunk/lib/asan/asan_malloc_linux.cc
+++ compiler-rt/trunk/lib/asan/asan_malloc_linux.cc
@@ -31,6 +31,7 @@
 using namespace __asan;  // NOLINT
 
 static uptr allocated_for_dlsym;
+static uptr last_dlsym_alloc_size_in_words;
 static const uptr kDlsymAllocPoolSize = SANITIZER_RTEMS ? 4096 : 1024;
 static uptr alloc_memory_for_dlsym[kDlsymAllocPoolSize];
 
@@ -42,11 +43,25 @@
 static void *AllocateFromLocalPool(uptr size_in_bytes) {
   uptr size_in_words = RoundUpTo(size_in_bytes, kWordSize) / kWordSize;
   void *mem = (void*)&alloc_memory_for_dlsym[allocated_for_dlsym];
+  last_dlsym_alloc_size_in_words = size_in_words;
   allocated_for_dlsym += size_in_words;
   CHECK_LT(allocated_for_dlsym, kDlsymAllocPoolSize);
   return mem;
 }
 
+static void DeallocateFromLocalPool(const void *ptr) {
+  // Hack: since glibc 2.27, dlsym longer use stack-allocated memory to store
+  // error messages and instead use malloc followed by free. To avoid pool
+  // exhaustion due to long object filenames, handle that special case here.
+  uptr prev_offset = allocated_for_dlsym - last_dlsym_alloc_size_in_words;
+  void *prev_mem = (void*)&alloc_memory_for_dlsym[prev_offset];
+  if (prev_mem == ptr) {
+    REAL(memset)(prev_mem, 0, last_dlsym_alloc_size_in_words * kWordSize);
+    allocated_for_dlsym = prev_offset;
+    last_dlsym_alloc_size_in_words = 0;
+  }
+}
+
 static int PosixMemalignFromLocalPool(void **memptr, uptr alignment,
                                       uptr size_in_bytes) {
   if (UNLIKELY(!CheckPosixMemalignAlignment(alignment)))
@@ -107,8 +122,10 @@
 
 INTERCEPTOR(void, free, void *ptr) {
   GET_STACK_TRACE_FREE;
-  if (UNLIKELY(IsInDlsymAllocPool(ptr)))
+  if (UNLIKELY(IsInDlsymAllocPool(ptr))) {
+    DeallocateFromLocalPool(ptr);
     return;
+  }
   asan_free(ptr, &stack, FROM_MALLOC);
 }
 
Index: compiler-rt/trunk/test/asan/TestCases/long-object-path.cc
===================================================================
--- compiler-rt/trunk/test/asan/TestCases/long-object-path.cc
+++ compiler-rt/trunk/test/asan/TestCases/long-object-path.cc
@@ -0,0 +1,7 @@
+// RUN: mkdir -p %T/a-long-directory-name-to-test-allocations-for-exceptions-in-_dl_lookup_symbol_x-since-glibc-2.27
+// RUN: %clangxx_asan -g %s -o %T/long-object-path
+// RUN: %run %T/a-*/../a-*/../a-*/../a-*/../a-*/../a-*/../a-*/../a-*/../long-object-path
+
+int main(void) {
+    return 0;
+}


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D47995.151324.patch
Type: text/x-patch
Size: 2533 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180614/af3244e6/attachment.bin>


More information about the llvm-commits mailing list