This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [committed] Cherry-pick upstream asan fix for upcoming glibc (PR sanitizer/71160)


Hi Jakub,

thanks for backporting this! Do you have any plans to apply this patch to GCC 5 and 6 branches? AFAIK people hit on this ASan + newer Glibc bug by using GCC 5.3.1 on Fedora 23.

On 17/05/16 12:23, Jakub Jelinek wrote:
Hi!

This is a cherry-pick of upstream fix, so that dlsym can call not just
calloc, but also malloc or realloc, even before asan is initialized.

Tested on x86_64-linux, committed so far to trunk.

IMHO even better would be to make sure that in the common case (recent
glibc) we don't have failed dlsym calls (still, this hack is useful just in
case) - the __isoc99_*printf* interceptors make no sense, glibc has never
exported those.  Thus, if we bump ABI of libasan again for GCC 7, IMHO those
bogus interceptors should be ifdefed out for glibc or removed completely.
Or, if we don't want to break ABI, at least changed so that they actuall
dlsym the corresponding *printf* (not __isoc99_ prefixed) functions
instead of the bogus ones.

We should definitely bump libasan version on next libsanitizer merge, because it would contain ABI breaking changes in ASan. Perhaps we could ifdef these __isoc99 interceptors as a local GCC patch then?

2016-05-17  Jakub Jelinek  <jakub@redhat.com>

	PR sanitizer/71160
	* asan/asan_malloc_linux.cc: Cherry pick upstream r254395
	and r269633.

--- libsanitizer/asan/asan_malloc_linux.cc.jj	2014-09-24 11:08:01.772039066 +0200
+++ libsanitizer/asan/asan_malloc_linux.cc	2016-05-17 11:02:37.859379380 +0200
@@ -24,39 +24,62 @@
  // ---------------------- Replacement functions ---------------- {{{1
  using namespace __asan;  // NOLINT
+static uptr allocated_for_dlsym;
+static const uptr kDlsymAllocPoolSize = 1024;
+static uptr alloc_memory_for_dlsym[kDlsymAllocPoolSize];
+
+static bool IsInDlsymAllocPool(const void *ptr) {
+  uptr off = (uptr)ptr - (uptr)alloc_memory_for_dlsym;
+  return off < sizeof(alloc_memory_for_dlsym);
+}
+
+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];
+  allocated_for_dlsym += size_in_words;
+  CHECK_LT(allocated_for_dlsym, kDlsymAllocPoolSize);
+  return mem;
+}
+
  INTERCEPTOR(void, free, void *ptr) {
    GET_STACK_TRACE_FREE;
+  if (UNLIKELY(IsInDlsymAllocPool(ptr)))
+    return;
    asan_free(ptr, &stack, FROM_MALLOC);
  }
INTERCEPTOR(void, cfree, void *ptr) {
    GET_STACK_TRACE_FREE;
+  if (UNLIKELY(IsInDlsymAllocPool(ptr)))
+    return;
    asan_free(ptr, &stack, FROM_MALLOC);
  }
INTERCEPTOR(void*, malloc, uptr size) {
+  if (UNLIKELY(!asan_inited))
+    // Hack: dlsym calls malloc before REAL(malloc) is retrieved from dlsym.
+    return AllocateFromLocalPool(size);
    GET_STACK_TRACE_MALLOC;
    return asan_malloc(size, &stack);
  }
INTERCEPTOR(void*, calloc, uptr nmemb, uptr size) {
-  if (UNLIKELY(!asan_inited)) {
+  if (UNLIKELY(!asan_inited))
      // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym.
-    const uptr kCallocPoolSize = 1024;
-    static uptr calloc_memory_for_dlsym[kCallocPoolSize];
-    static uptr allocated;
-    uptr size_in_words = ((nmemb * size) + kWordSize - 1) / kWordSize;
-    void *mem = (void*)&calloc_memory_for_dlsym[allocated];
-    allocated += size_in_words;
-    CHECK(allocated < kCallocPoolSize);
-    return mem;
-  }
+    return AllocateFromLocalPool(nmemb * size);
    GET_STACK_TRACE_MALLOC;
    return asan_calloc(nmemb, size, &stack);
  }
INTERCEPTOR(void*, realloc, void *ptr, uptr size) {
    GET_STACK_TRACE_MALLOC;
+  if (UNLIKELY(IsInDlsymAllocPool(ptr))) {
+    uptr offset = (uptr)ptr - (uptr)alloc_memory_for_dlsym;
+    uptr copy_size = Min(size, kDlsymAllocPoolSize - offset);
+    void *new_ptr = asan_malloc(size, &stack);
+    internal_memcpy(new_ptr, ptr, copy_size);
+    return new_ptr;
+  }
    return asan_realloc(ptr, size, &stack);
  }
	Jakub




Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]