forked from OSchip/llvm-project
[asan] Fix internal CHECK failure on double free in recovery mode.
This patches fixes https://github.com/google/sanitizers/issues/639 Differential Revision: http://reviews.llvm.org/D15807 llvm-svn: 259473
This commit is contained in:
parent
05aecba118
commit
4a3c7fa441
|
@ -457,18 +457,25 @@ struct Allocator {
|
|||
return res;
|
||||
}
|
||||
|
||||
void AtomicallySetQuarantineFlag(AsanChunk *m, void *ptr,
|
||||
// Set quarantine flag if chunk is allocated, issue ASan error report on
|
||||
// available and quarantined chunks. Return true on success, false otherwise.
|
||||
bool AtomicallySetQuarantineFlagIfAllocated(AsanChunk *m, void *ptr,
|
||||
BufferedStackTrace *stack) {
|
||||
u8 old_chunk_state = CHUNK_ALLOCATED;
|
||||
// Flip the chunk_state atomically to avoid race on double-free.
|
||||
if (!atomic_compare_exchange_strong((atomic_uint8_t*)m, &old_chunk_state,
|
||||
CHUNK_QUARANTINE, memory_order_acquire))
|
||||
if (!atomic_compare_exchange_strong((atomic_uint8_t *)m, &old_chunk_state,
|
||||
CHUNK_QUARANTINE,
|
||||
memory_order_acquire)) {
|
||||
ReportInvalidFree(ptr, old_chunk_state, stack);
|
||||
// It's not safe to push a chunk in quarantine on invalid free.
|
||||
return false;
|
||||
}
|
||||
CHECK_EQ(CHUNK_ALLOCATED, old_chunk_state);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Expects the chunk to already be marked as quarantined by using
|
||||
// AtomicallySetQuarantineFlag.
|
||||
// AtomicallySetQuarantineFlagIfAllocated.
|
||||
void QuarantineChunk(AsanChunk *m, void *ptr, BufferedStackTrace *stack,
|
||||
AllocType alloc_type) {
|
||||
CHECK_EQ(m->chunk_state, CHUNK_QUARANTINE);
|
||||
|
@ -522,7 +529,8 @@ struct Allocator {
|
|||
}
|
||||
ASAN_FREE_HOOK(ptr);
|
||||
// Must mark the chunk as quarantined before any changes to its metadata.
|
||||
AtomicallySetQuarantineFlag(m, ptr, stack);
|
||||
// Do not quarantine given chunk if we failed to set CHUNK_QUARANTINE flag.
|
||||
if (!AtomicallySetQuarantineFlagIfAllocated(m, ptr, stack)) return;
|
||||
QuarantineChunk(m, ptr, stack, alloc_type);
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,10 @@
|
|||
// Also works if no malloc context is available.
|
||||
// RUN: %env_asan_opts=malloc_context_size=0:fast_unwind_on_malloc=0 not %run %t 2>&1 | FileCheck %s
|
||||
// RUN: %env_asan_opts=malloc_context_size=0:fast_unwind_on_malloc=1 not %run %t 2>&1 | FileCheck %s
|
||||
|
||||
// RUN: %clangxx_asan -O0 -fsanitize-recover=address %s -o %t 2>&1
|
||||
// RUN: %env_asan_opts=halt_on_error=false %run %t 2>&1 | FileCheck %s --check-prefix CHECK-RECOVER
|
||||
|
||||
// XFAIL: arm-linux-gnueabi
|
||||
// XFAIL: armv7l-unknown-linux-gnueabihf
|
||||
|
||||
|
@ -23,5 +27,7 @@ int main(int argc, char **argv) {
|
|||
// MALLOC-CTX: #1 0x{{.*}} in main {{.*}}double-free.cc:[[@LINE-7]]
|
||||
// CHECK: allocated by thread T0 here:
|
||||
// MALLOC-CTX: double-free.cc:[[@LINE-12]]
|
||||
// CHECK-RECOVER: AddressSanitizer: attempting double-free{{.*}}in thread T0
|
||||
// CHECK-RECOVER-NOT: AddressSanitizer CHECK failed:
|
||||
return res;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue