[llvm-commits] [compiler-rt] r154097 - in /compiler-rt/trunk/lib/asan: asan_allocator.cc asan_internal.h asan_posix.cc asan_win.cc

Kostya Serebryany kcc at google.com
Thu Apr 5 08:55:10 PDT 2012


Author: kcc
Date: Thu Apr  5 10:55:09 2012
New Revision: 154097

URL: http://llvm.org/viewvc/llvm-project?rev=154097&view=rev
Log:
[asan] make __asan::Deallocate immune to racy double-free (issue #57)

Modified:
    compiler-rt/trunk/lib/asan/asan_allocator.cc
    compiler-rt/trunk/lib/asan/asan_internal.h
    compiler-rt/trunk/lib/asan/asan_posix.cc
    compiler-rt/trunk/lib/asan/asan_win.cc

Modified: compiler-rt/trunk/lib/asan/asan_allocator.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_allocator.cc?rev=154097&r1=154096&r2=154097&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_allocator.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_allocator.cc Thu Apr  5 10:55:09 2012
@@ -704,18 +704,22 @@
 
   // Printf("Deallocate %p\n", ptr);
   AsanChunk *m = PtrToChunk((uintptr_t)ptr);
-  if (m->chunk_state == CHUNK_QUARANTINE) {
+
+  // Flip the state atomically to avoid race on double-free.
+  uint16_t old_chunk_state = AtomicExchange(&m->chunk_state, CHUNK_QUARANTINE);
+
+  if (old_chunk_state == CHUNK_QUARANTINE) {
     Report("ERROR: AddressSanitizer attempting double-free on %p:\n", ptr);
     stack->PrintStack();
     Describe((uintptr_t)ptr, 1);
     ShowStatsAndAbort();
-  } else if (m->chunk_state != CHUNK_ALLOCATED) {
+  } else if (old_chunk_state != CHUNK_ALLOCATED) {
     Report("ERROR: AddressSanitizer attempting free on address which was not"
            " malloc()-ed: %p\n", ptr);
     stack->PrintStack();
     ShowStatsAndAbort();
   }
-  CHECK(m->chunk_state == CHUNK_ALLOCATED);
+  CHECK(old_chunk_state == CHUNK_ALLOCATED);
   CHECK(m->free_tid == AsanThread::kInvalidTid);
   CHECK(m->alloc_tid >= 0);
   AsanThread *t = asanThreadRegistry().GetCurrent();
@@ -731,7 +735,7 @@
   thread_stats.freed += m->used_size;
   thread_stats.freed_by_size[m->SizeClass()]++;
 
-  m->chunk_state = CHUNK_QUARANTINE;
+  CHECK(m->chunk_state == CHUNK_QUARANTINE);
   if (t) {
     AsanThreadLocalMallocStorage *ms = &t->malloc_storage();
     CHECK(!m->next);

Modified: compiler-rt/trunk/lib/asan/asan_internal.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_internal.h?rev=154097&r1=154096&r2=154097&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_internal.h (original)
+++ compiler-rt/trunk/lib/asan/asan_internal.h Thu Apr  5 10:55:09 2012
@@ -187,6 +187,7 @@
 int GetPid();
 uintptr_t GetThreadSelf();
 int AtomicInc(int *a);
+uint16_t AtomicExchange(uint16_t *a, uint16_t new_val);
 
 // Wrapper for TLS/TSD.
 void AsanTSDInit(void (*destructor)(void *tsd));

Modified: compiler-rt/trunk/lib/asan/asan_posix.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_posix.cc?rev=154097&r1=154096&r2=154097&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_posix.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_posix.cc Thu Apr  5 10:55:09 2012
@@ -152,6 +152,10 @@
 #endif
 }
 
+uint16_t AtomicExchange(uint16_t *a, uint16_t new_val) {
+  return __sync_lock_test_and_set(a, new_val);
+}
+
 void SortArray(uintptr_t *array, size_t size) {
   std::sort(array, array + size);
 }

Modified: compiler-rt/trunk/lib/asan/asan_win.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_win.cc?rev=154097&r1=154096&r2=154097&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_win.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_win.cc Thu Apr  5 10:55:09 2012
@@ -234,6 +234,10 @@
   return InterlockedExchangeAdd((LONG*)a, 1) + 1;
 }
 
+uint16_t AtomicExchange(uint16_t *a, uint16_t new_val) {
+  return InterlockedExchange16(a, new_val);
+}
+
 const char* AsanGetEnv(const char* name) {
   static char env_buffer[32767] = {};
 





More information about the llvm-commits mailing list