summaryrefslogtreecommitdiffstats
path: root/compiler-rt/lib/asan/asan_allocator.cc
diff options
context:
space:
mode:
authorKostya Serebryany <kcc@google.com>2012-04-05 15:55:09 +0000
committerKostya Serebryany <kcc@google.com>2012-04-05 15:55:09 +0000
commit7a8f5e4d1edaba944ed5174d6d22da692dd9b7f0 (patch)
treec24eafded12f3fd1c753443455c318e492893c23 /compiler-rt/lib/asan/asan_allocator.cc
parentd6825173d35e2506682784f0981be506c5fd7db7 (diff)
downloadbcm5719-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.cc12
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);
OpenPOWER on IntegriCloud