diff options
| author | Kostya Serebryany <kcc@google.com> | 2012-04-05 15:55:09 +0000 |
|---|---|---|
| committer | Kostya Serebryany <kcc@google.com> | 2012-04-05 15:55:09 +0000 |
| commit | 7a8f5e4d1edaba944ed5174d6d22da692dd9b7f0 (patch) | |
| tree | c24eafded12f3fd1c753443455c318e492893c23 /compiler-rt/lib/asan/asan_allocator.cc | |
| parent | d6825173d35e2506682784f0981be506c5fd7db7 (diff) | |
| download | bcm5719-llvm-7a8f5e4d1edaba944ed5174d6d22da692dd9b7f0.tar.gz bcm5719-llvm-7a8f5e4d1edaba944ed5174d6d22da692dd9b7f0.zip | |
[asan] make __asan::Deallocate immune to racy double-free (issue #57)
llvm-svn: 154097
Diffstat (limited to 'compiler-rt/lib/asan/asan_allocator.cc')
| -rw-r--r-- | compiler-rt/lib/asan/asan_allocator.cc | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/compiler-rt/lib/asan/asan_allocator.cc b/compiler-rt/lib/asan/asan_allocator.cc index 3797a0978cb..8c3cc00cf46 100644 --- a/compiler-rt/lib/asan/asan_allocator.cc +++ b/compiler-rt/lib/asan/asan_allocator.cc @@ -704,18 +704,22 @@ static void Deallocate(uint8_t *ptr, AsanStackTrace *stack) { // 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 @@ static void Deallocate(uint8_t *ptr, AsanStackTrace *stack) { 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); |

