[llvm-commits] [compiler-rt] r170869 - in /compiler-rt/trunk/lib/asan: asan_allocator.cc asan_allocator.h asan_allocator2.cc asan_flags.h asan_mac.cc asan_malloc_linux.cc asan_malloc_mac.cc asan_malloc_win.cc asan_new_delete.cc asan_report.cc asan_report.h asan_rtl.cc lit_tests/deep_stack_uaf.cc lit_tests/malloc_delete_mismatch.cc tests/asan_noinst_test.cc tests/asan_test.cc
Kostya Serebryany
kcc at google.com
Fri Dec 21 00:54:00 PST 2012
Author: kcc
Date: Fri Dec 21 02:53:59 2012
New Revision: 170869
URL: http://llvm.org/viewvc/llvm-project?rev=170869&view=rev
Log:
[asan] add a flag alloc_dealloc_mismatch (off by default for now) which finds malloc/delete, new/free, new/delete[], etc mismatches
Added:
compiler-rt/trunk/lib/asan/lit_tests/malloc_delete_mismatch.cc
Modified:
compiler-rt/trunk/lib/asan/asan_allocator.cc
compiler-rt/trunk/lib/asan/asan_allocator.h
compiler-rt/trunk/lib/asan/asan_allocator2.cc
compiler-rt/trunk/lib/asan/asan_flags.h
compiler-rt/trunk/lib/asan/asan_mac.cc
compiler-rt/trunk/lib/asan/asan_malloc_linux.cc
compiler-rt/trunk/lib/asan/asan_malloc_mac.cc
compiler-rt/trunk/lib/asan/asan_malloc_win.cc
compiler-rt/trunk/lib/asan/asan_new_delete.cc
compiler-rt/trunk/lib/asan/asan_report.cc
compiler-rt/trunk/lib/asan/asan_report.h
compiler-rt/trunk/lib/asan/asan_rtl.cc
compiler-rt/trunk/lib/asan/lit_tests/deep_stack_uaf.cc
compiler-rt/trunk/lib/asan/tests/asan_noinst_test.cc
compiler-rt/trunk/lib/asan/tests/asan_test.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=170869&r1=170868&r2=170869&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_allocator.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_allocator.cc Fri Dec 21 02:53:59 2012
@@ -128,7 +128,8 @@
// Second 8 bytes.
uptr alignment_log : 8;
- uptr used_size : FIRST_32_SECOND_64(32, 56); // Size requested by the user.
+ uptr alloc_type : 2;
+ uptr used_size : FIRST_32_SECOND_64(32, 54); // Size requested by the user.
// This field may overlap with the user area and thus should not
// be used while the chunk is in CHUNK_ALLOCATED state.
@@ -497,7 +498,8 @@
return AsanChunkView(malloc_info.FindChunkByAddr(address));
}
-static u8 *Allocate(uptr alignment, uptr size, StackTrace *stack) {
+static u8 *Allocate(uptr alignment, uptr size, StackTrace *stack,
+ AllocType alloc_type) {
__asan_init();
CHECK(stack);
if (size == 0) {
@@ -554,6 +556,7 @@
CHECK(m);
CHECK(m->chunk_state == CHUNK_AVAILABLE);
m->chunk_state = CHUNK_ALLOCATED;
+ m->alloc_type = alloc_type;
m->next = 0;
CHECK(m->Size() == size_to_allocate);
uptr addr = (uptr)m + REDZONE;
@@ -588,7 +591,7 @@
return (u8*)addr;
}
-static void Deallocate(u8 *ptr, StackTrace *stack) {
+static void Deallocate(u8 *ptr, StackTrace *stack, AllocType alloc_type) {
if (!ptr) return;
CHECK(stack);
@@ -609,6 +612,9 @@
ReportFreeNotMalloced((uptr)ptr, stack);
}
CHECK(old_chunk_state == CHUNK_ALLOCATED);
+ if (m->alloc_type != alloc_type && flags()->alloc_dealloc_mismatch)
+ ReportAllocTypeMismatch((uptr)ptr, stack,
+ (AllocType)m->alloc_type, (AllocType)alloc_type);
// With REDZONE==16 m->next is in the user area, otherwise it should be 0.
CHECK(REDZONE <= 16 || !m->next);
CHECK(m->free_tid == kInvalidTid);
@@ -653,11 +659,11 @@
CHECK(m->chunk_state == CHUNK_ALLOCATED);
uptr old_size = m->used_size;
uptr memcpy_size = Min(new_size, old_size);
- u8 *new_ptr = Allocate(0, new_size, stack);
+ u8 *new_ptr = Allocate(0, new_size, stack, FROM_MALLOC);
if (new_ptr) {
CHECK(REAL(memcpy) != 0);
REAL(memcpy)(new_ptr, old_ptr, memcpy_size);
- Deallocate(old_ptr, stack);
+ Deallocate(old_ptr, stack, FROM_MALLOC);
}
return new_ptr;
}
@@ -682,27 +688,28 @@
namespace __asan {
SANITIZER_INTERFACE_ATTRIBUTE
-void *asan_memalign(uptr alignment, uptr size, StackTrace *stack) {
- void *ptr = (void*)Allocate(alignment, size, stack);
+void *asan_memalign(uptr alignment, uptr size, StackTrace *stack,
+ AllocType alloc_type) {
+ void *ptr = (void*)Allocate(alignment, size, stack, alloc_type);
ASAN_MALLOC_HOOK(ptr, size);
return ptr;
}
SANITIZER_INTERFACE_ATTRIBUTE
-void asan_free(void *ptr, StackTrace *stack) {
+void asan_free(void *ptr, StackTrace *stack, AllocType alloc_type) {
ASAN_FREE_HOOK(ptr);
- Deallocate((u8*)ptr, stack);
+ Deallocate((u8*)ptr, stack, alloc_type);
}
SANITIZER_INTERFACE_ATTRIBUTE
void *asan_malloc(uptr size, StackTrace *stack) {
- void *ptr = (void*)Allocate(0, size, stack);
+ void *ptr = (void*)Allocate(0, size, stack, FROM_MALLOC);
ASAN_MALLOC_HOOK(ptr, size);
return ptr;
}
void *asan_calloc(uptr nmemb, uptr size, StackTrace *stack) {
- void *ptr = (void*)Allocate(0, nmemb * size, stack);
+ void *ptr = (void*)Allocate(0, nmemb * size, stack, FROM_MALLOC);
if (ptr)
REAL(memset)(ptr, 0, nmemb * size);
ASAN_MALLOC_HOOK(ptr, size);
@@ -711,19 +718,19 @@
void *asan_realloc(void *p, uptr size, StackTrace *stack) {
if (p == 0) {
- void *ptr = (void*)Allocate(0, size, stack);
+ void *ptr = (void*)Allocate(0, size, stack, FROM_MALLOC);
ASAN_MALLOC_HOOK(ptr, size);
return ptr;
} else if (size == 0) {
ASAN_FREE_HOOK(p);
- Deallocate((u8*)p, stack);
+ Deallocate((u8*)p, stack, FROM_MALLOC);
return 0;
}
return Reallocate((u8*)p, size, stack);
}
void *asan_valloc(uptr size, StackTrace *stack) {
- void *ptr = (void*)Allocate(GetPageSizeCached(), size, stack);
+ void *ptr = (void*)Allocate(GetPageSizeCached(), size, stack, FROM_MALLOC);
ASAN_MALLOC_HOOK(ptr, size);
return ptr;
}
@@ -735,14 +742,14 @@
// pvalloc(0) should allocate one page.
size = PageSize;
}
- void *ptr = (void*)Allocate(PageSize, size, stack);
+ void *ptr = (void*)Allocate(PageSize, size, stack, FROM_MALLOC);
ASAN_MALLOC_HOOK(ptr, size);
return ptr;
}
int asan_posix_memalign(void **memptr, uptr alignment, uptr size,
StackTrace *stack) {
- void *ptr = Allocate(alignment, size, stack);
+ void *ptr = Allocate(alignment, size, stack, FROM_MALLOC);
CHECK(IsAligned((uptr)ptr, alignment));
ASAN_MALLOC_HOOK(ptr, size);
*memptr = ptr;
Modified: compiler-rt/trunk/lib/asan/asan_allocator.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_allocator.h?rev=170869&r1=170868&r2=170869&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_allocator.h (original)
+++ compiler-rt/trunk/lib/asan/asan_allocator.h Fri Dec 21 02:53:59 2012
@@ -27,6 +27,12 @@
namespace __asan {
+enum AllocType {
+ FROM_MALLOC = 1, // Memory block came from malloc, calloc, realloc, etc.
+ FROM_NEW = 2, // Memory block came from operator new.
+ FROM_NEW_BR = 3 // Memory block came from operator new [ ]
+};
+
static const uptr kNumberOfSizeClasses = 255;
struct AsanChunk;
@@ -190,8 +196,9 @@
FakeFrameLifo call_stack_;
};
-void *asan_memalign(uptr alignment, uptr size, StackTrace *stack);
-void asan_free(void *ptr, StackTrace *stack);
+void *asan_memalign(uptr alignment, uptr size, StackTrace *stack,
+ AllocType alloc_type);
+void asan_free(void *ptr, StackTrace *stack, AllocType alloc_type);
void *asan_malloc(uptr size, StackTrace *stack);
void *asan_calloc(uptr nmemb, uptr size, StackTrace *stack);
Modified: compiler-rt/trunk/lib/asan/asan_allocator2.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_allocator2.cc?rev=170869&r1=170868&r2=170869&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_allocator2.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_allocator2.cc Fri Dec 21 02:53:59 2012
@@ -124,8 +124,10 @@
// 1-st 8 bytes.
uptr chunk_state : 8; // Must be first.
uptr alloc_tid : 24;
+
uptr free_tid : 24;
uptr from_memalign : 1;
+ uptr alloc_type : 2;
// 2-nd 8 bytes
uptr user_requested_size;
// Header2 (intersects with user memory).
@@ -141,7 +143,9 @@
// 1-st 8 bytes.
uptr chunk_state : 8; // Must be first.
uptr alloc_tid : 24;
+
uptr from_memalign : 1;
+ uptr alloc_type : 2;
uptr free_tid : 24;
// 2-nd 8 bytes
uptr user_requested_size;
@@ -271,7 +275,8 @@
return res;
}
-static void *Allocate(uptr size, uptr alignment, StackTrace *stack) {
+static void *Allocate(uptr size, uptr alignment, StackTrace *stack,
+ AllocType alloc_type) {
Init();
CHECK(stack);
if (alignment < 8) alignment = 8;
@@ -306,6 +311,7 @@
uptr chunk_beg = user_beg - kChunkHeaderSize;
AsanChunk *m = reinterpret_cast<AsanChunk *>(chunk_beg);
m->chunk_state = CHUNK_ALLOCATED;
+ m->alloc_type = alloc_type;
u32 alloc_tid = t ? t->tid() : 0;
m->alloc_tid = alloc_tid;
CHECK_EQ(alloc_tid, m->alloc_tid); // Does alloc_tid fit into the bitfield?
@@ -339,7 +345,7 @@
return res;
}
-static void Deallocate(void *ptr, StackTrace *stack) {
+static void Deallocate(void *ptr, StackTrace *stack, AllocType alloc_type) {
uptr p = reinterpret_cast<uptr>(ptr);
if (p == 0 || p == kReturnOnZeroMalloc) return;
uptr chunk_beg = p - kChunkHeaderSize;
@@ -354,6 +360,9 @@
else if (old_chunk_state != CHUNK_ALLOCATED)
ReportFreeNotMalloced((uptr)ptr, stack);
CHECK(old_chunk_state == CHUNK_ALLOCATED);
+ if (m->alloc_type != alloc_type && flags()->alloc_dealloc_mismatch)
+ ReportAllocTypeMismatch((uptr)ptr, stack,
+ (AllocType)m->alloc_type, (AllocType)alloc_type);
CHECK_GE(m->alloc_tid, 0);
if (SANITIZER_WORDSIZE == 64) // On 32-bits this resides in user area.
@@ -394,11 +403,11 @@
CHECK(m->chunk_state == CHUNK_ALLOCATED);
uptr old_size = m->UsedSize();
uptr memcpy_size = Min(new_size, old_size);
- void *new_ptr = Allocate(new_size, 8, stack);
+ void *new_ptr = Allocate(new_size, 8, stack, FROM_MALLOC);
if (new_ptr) {
CHECK(REAL(memcpy) != 0);
REAL(memcpy)(new_ptr, old_ptr, memcpy_size);
- Deallocate(old_ptr, stack);
+ Deallocate(old_ptr, stack, FROM_MALLOC);
}
return new_ptr;
}
@@ -471,22 +480,23 @@
}
SANITIZER_INTERFACE_ATTRIBUTE
-void *asan_memalign(uptr alignment, uptr size, StackTrace *stack) {
- return Allocate(size, alignment, stack);
+void *asan_memalign(uptr alignment, uptr size, StackTrace *stack,
+ AllocType alloc_type) {
+ return Allocate(size, alignment, stack, alloc_type);
}
SANITIZER_INTERFACE_ATTRIBUTE
-void asan_free(void *ptr, StackTrace *stack) {
- Deallocate(ptr, stack);
+void asan_free(void *ptr, StackTrace *stack, AllocType alloc_type) {
+ Deallocate(ptr, stack, alloc_type);
}
SANITIZER_INTERFACE_ATTRIBUTE
void *asan_malloc(uptr size, StackTrace *stack) {
- return Allocate(size, 8, stack);
+ return Allocate(size, 8, stack, FROM_MALLOC);
}
void *asan_calloc(uptr nmemb, uptr size, StackTrace *stack) {
- void *ptr = Allocate(nmemb * size, 8, stack);
+ void *ptr = Allocate(nmemb * size, 8, stack, FROM_MALLOC);
if (ptr)
REAL(memset)(ptr, 0, nmemb * size);
return ptr;
@@ -494,16 +504,16 @@
void *asan_realloc(void *p, uptr size, StackTrace *stack) {
if (p == 0)
- return Allocate(size, 8, stack);
+ return Allocate(size, 8, stack, FROM_MALLOC);
if (size == 0) {
- Deallocate(p, stack);
+ Deallocate(p, stack, FROM_MALLOC);
return 0;
}
return Reallocate(p, size, stack);
}
void *asan_valloc(uptr size, StackTrace *stack) {
- return Allocate(size, GetPageSizeCached(), stack);
+ return Allocate(size, GetPageSizeCached(), stack, FROM_MALLOC);
}
void *asan_pvalloc(uptr size, StackTrace *stack) {
@@ -513,12 +523,12 @@
// pvalloc(0) should allocate one page.
size = PageSize;
}
- return Allocate(size, PageSize, stack);
+ return Allocate(size, PageSize, stack, FROM_MALLOC);
}
int asan_posix_memalign(void **memptr, uptr alignment, uptr size,
StackTrace *stack) {
- void *ptr = Allocate(size, alignment, stack);
+ void *ptr = Allocate(size, alignment, stack, FROM_MALLOC);
CHECK(IsAligned((uptr)ptr, alignment));
*memptr = ptr;
return 0;
Modified: compiler-rt/trunk/lib/asan/asan_flags.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_flags.h?rev=170869&r1=170868&r2=170869&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_flags.h (original)
+++ compiler-rt/trunk/lib/asan/asan_flags.h Fri Dec 21 02:53:59 2012
@@ -102,6 +102,8 @@
// Poison (or not) the heap memory on [de]allocation. Zero value is useful
// for benchmarking the allocator or instrumentator.
bool poison_heap;
+ // Report errors on malloc/delete, new/free, new/delete[], etc.
+ bool alloc_dealloc_mismatch;
};
Flags *flags();
Modified: compiler-rt/trunk/lib/asan/asan_mac.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_mac.cc?rev=170869&r1=170868&r2=170869&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_mac.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_mac.cc Fri Dec 21 02:53:59 2012
@@ -319,7 +319,7 @@
asan_register_worker_thread(context->parent_tid, &stack);
// Call the original dispatcher for the block.
context->func(context->block);
- asan_free(context, &stack);
+ asan_free(context, &stack, FROM_MALLOC);
}
} // namespace __asan
@@ -461,7 +461,7 @@
worker_t fn = (worker_t)(ctxt->func);
void *result = fn(ctxt->block);
GET_STACK_TRACE_THREAD;
- asan_free(arg, &stack);
+ asan_free(arg, &stack, FROM_MALLOC);
return result;
}
Modified: compiler-rt/trunk/lib/asan/asan_malloc_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_malloc_linux.cc?rev=170869&r1=170868&r2=170869&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_malloc_linux.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_malloc_linux.cc Fri Dec 21 02:53:59 2012
@@ -61,12 +61,12 @@
INTERCEPTOR(void, free, void *ptr) {
GET_STACK_TRACE_FREE;
- asan_free(ptr, &stack);
+ asan_free(ptr, &stack, FROM_MALLOC);
}
INTERCEPTOR(void, cfree, void *ptr) {
GET_STACK_TRACE_FREE;
- asan_free(ptr, &stack);
+ asan_free(ptr, &stack, FROM_MALLOC);
}
INTERCEPTOR(void*, malloc, uptr size) {
@@ -97,7 +97,7 @@
INTERCEPTOR(void*, memalign, uptr boundary, uptr size) {
GET_STACK_TRACE_MALLOC;
- return asan_memalign(boundary, size, &stack);
+ return asan_memalign(boundary, size, &stack, FROM_MALLOC);
}
INTERCEPTOR(void*, __libc_memalign, uptr align, uptr s)
Modified: compiler-rt/trunk/lib/asan/asan_malloc_mac.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_malloc_mac.cc?rev=170869&r1=170868&r2=170869&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_malloc_mac.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_malloc_mac.cc Fri Dec 21 02:53:59 2012
@@ -93,7 +93,7 @@
} else {
if (!asan_mz_size(ptr)) ptr = get_saved_cfallocator_ref(ptr);
GET_STACK_TRACE_FREE;
- asan_free(ptr, &stack);
+ asan_free(ptr, &stack, FROM_MALLOC);
}
}
@@ -165,7 +165,7 @@
return malloc_zone_valloc(system_malloc_zone, size);
}
GET_STACK_TRACE_MALLOC;
- return asan_memalign(GetPageSizeCached(), size, &stack);
+ return asan_memalign(GetPageSizeCached(), size, &stack, FROM_MALLOC);
}
#define GET_ZONE_FOR_PTR(ptr) \
@@ -176,7 +176,7 @@
if (!ptr) return;
if (asan_mz_size(ptr)) {
GET_STACK_TRACE_FREE;
- asan_free(ptr, &stack);
+ asan_free(ptr, &stack, FROM_MALLOC);
} else {
// If the pointer does not belong to any of the zones, use one of the
// fallback methods to free memory.
@@ -192,7 +192,7 @@
ptr = get_saved_cfallocator_ref(ptr);
GET_STACK_TRACE_FREE;
if (!flags()->mac_ignore_invalid_free) {
- asan_free(ptr, &stack);
+ asan_free(ptr, &stack, FROM_MALLOC);
} else {
GET_ZONE_FOR_PTR(ptr);
WarnMacFreeUnallocated((uptr)ptr, (uptr)zone_ptr, zone_name, &stack);
@@ -262,7 +262,7 @@
return malloc_zone_memalign(system_malloc_zone, align, size);
}
GET_STACK_TRACE_MALLOC;
- return asan_memalign(align, size, &stack);
+ return asan_memalign(align, size, &stack, FROM_MALLOC);
}
// This function is currently unused, and we build with -Werror.
Modified: compiler-rt/trunk/lib/asan/asan_malloc_win.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_malloc_win.cc?rev=170869&r1=170868&r2=170869&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_malloc_win.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_malloc_win.cc Fri Dec 21 02:53:59 2012
@@ -32,7 +32,7 @@
extern "C" {
void free(void *ptr) {
GET_STACK_TRACE_FREE;
- return asan_free(ptr, &stack);
+ return asan_free(ptr, &stack, FROM_MALLOC);
}
void _free_dbg(void* ptr, int) {
Modified: compiler-rt/trunk/lib/asan/asan_new_delete.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_new_delete.cc?rev=170869&r1=170868&r2=170869&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_new_delete.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_new_delete.cc Fri Dec 21 02:53:59 2012
@@ -35,32 +35,34 @@
struct nothrow_t {};
} // namespace std
-#define OPERATOR_NEW_BODY \
+#define OPERATOR_NEW_BODY(type) \
GET_STACK_TRACE_MALLOC;\
- return asan_memalign(0, size, &stack);
+ return asan_memalign(0, size, &stack, type);
INTERCEPTOR_ATTRIBUTE
-void *operator new(size_t size) { OPERATOR_NEW_BODY; }
+void *operator new(size_t size) { OPERATOR_NEW_BODY(FROM_NEW); }
INTERCEPTOR_ATTRIBUTE
-void *operator new[](size_t size) { OPERATOR_NEW_BODY; }
+void *operator new[](size_t size) { OPERATOR_NEW_BODY(FROM_NEW_BR); }
INTERCEPTOR_ATTRIBUTE
-void *operator new(size_t size, std::nothrow_t const&) { OPERATOR_NEW_BODY; }
+void *operator new(size_t size, std::nothrow_t const&)
+{ OPERATOR_NEW_BODY(FROM_NEW); }
INTERCEPTOR_ATTRIBUTE
-void *operator new[](size_t size, std::nothrow_t const&) { OPERATOR_NEW_BODY; }
+void *operator new[](size_t size, std::nothrow_t const&)
+{ OPERATOR_NEW_BODY(FROM_NEW_BR); }
-#define OPERATOR_DELETE_BODY \
+#define OPERATOR_DELETE_BODY(type) \
GET_STACK_TRACE_FREE;\
- asan_free(ptr, &stack);
+ asan_free(ptr, &stack, type);
INTERCEPTOR_ATTRIBUTE
-void operator delete(void *ptr) { OPERATOR_DELETE_BODY; }
+void operator delete(void *ptr) { OPERATOR_DELETE_BODY(FROM_NEW); }
INTERCEPTOR_ATTRIBUTE
-void operator delete[](void *ptr) { OPERATOR_DELETE_BODY; }
+void operator delete[](void *ptr) { OPERATOR_DELETE_BODY(FROM_NEW_BR); }
INTERCEPTOR_ATTRIBUTE
void operator delete(void *ptr, std::nothrow_t const&)
-{ OPERATOR_DELETE_BODY; }
+{ OPERATOR_DELETE_BODY(FROM_NEW); }
INTERCEPTOR_ATTRIBUTE
void operator delete[](void *ptr, std::nothrow_t const&)
-{ OPERATOR_DELETE_BODY; }
+{ OPERATOR_DELETE_BODY(FROM_NEW_BR); }
#endif
Modified: compiler-rt/trunk/lib/asan/asan_report.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_report.cc?rev=170869&r1=170868&r2=170869&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_report.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_report.cc Fri Dec 21 02:53:59 2012
@@ -488,6 +488,26 @@
DescribeHeapAddress(addr, 1);
}
+void ReportAllocTypeMismatch(uptr addr, StackTrace *stack,
+ AllocType alloc_type,
+ AllocType dealloc_type) {
+ static const char *alloc_names[] =
+ {"INVALID", "malloc", "operator new", "operator new []"};
+ static const char *dealloc_names[] =
+ {"INVALID", "free", "operator delete", "operator delete []"};
+ CHECK_NE(alloc_type, dealloc_type);
+ ScopedInErrorReport in_report;
+ Decorator d;
+ Printf("%s", d.Warning());
+ Report("ERROR: AddressSanitizer: alloc-dealloc-mismatch (%s vs %s) on %p\n",
+ alloc_names[alloc_type], dealloc_names[dealloc_type], addr);
+ Printf("%s", d.EndWarning());
+ PrintStack(stack);
+ DescribeHeapAddress(addr, 1);
+ Report("HINT: if you don't care about these warnings you may set "
+ "ASAN_OPTIONS=alloc_dealloc_mismatch=0\n");
+}
+
void ReportMallocUsableSizeNotOwned(uptr addr, StackTrace *stack) {
ScopedInErrorReport in_report;
Decorator d;
Modified: compiler-rt/trunk/lib/asan/asan_report.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_report.h?rev=170869&r1=170868&r2=170869&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_report.h (original)
+++ compiler-rt/trunk/lib/asan/asan_report.h Fri Dec 21 02:53:59 2012
@@ -12,6 +12,7 @@
// ASan-private header for error reporting functions.
//===----------------------------------------------------------------------===//
+#include "asan_allocator.h"
#include "asan_internal.h"
#include "asan_thread.h"
#include "sanitizer/asan_interface.h"
@@ -34,6 +35,9 @@
void NORETURN ReportSIGSEGV(uptr pc, uptr sp, uptr bp, uptr addr);
void NORETURN ReportDoubleFree(uptr addr, StackTrace *stack);
void NORETURN ReportFreeNotMalloced(uptr addr, StackTrace *stack);
+void NORETURN ReportAllocTypeMismatch(uptr addr, StackTrace *stack,
+ AllocType alloc_type,
+ AllocType dealloc_type);
void NORETURN ReportMallocUsableSizeNotOwned(uptr addr,
StackTrace *stack);
void NORETURN ReportAsanGetAllocatedSizeNotOwned(uptr addr,
Modified: compiler-rt/trunk/lib/asan/asan_rtl.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_rtl.cc?rev=170869&r1=170868&r2=170869&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_rtl.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_rtl.cc Fri Dec 21 02:53:59 2012
@@ -107,6 +107,7 @@
ParseFlag(str, &f->fast_unwind_on_fatal, "fast_unwind_on_fatal");
ParseFlag(str, &f->fast_unwind_on_malloc, "fast_unwind_on_malloc");
ParseFlag(str, &f->poison_heap, "poison_heap");
+ ParseFlag(str, &f->alloc_dealloc_mismatch, "alloc_dealloc_mismatch");
}
void InitializeFlags(Flags *f, const char *env) {
@@ -143,6 +144,7 @@
f->fast_unwind_on_fatal = true;
f->fast_unwind_on_malloc = true;
f->poison_heap = true;
+ f->alloc_dealloc_mismatch = false;
// Override from user-specified string.
ParseFlagsFromString(f, MaybeCallAsanDefaultOptions());
Modified: compiler-rt/trunk/lib/asan/lit_tests/deep_stack_uaf.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/lit_tests/deep_stack_uaf.cc?rev=170869&r1=170868&r2=170869&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/lit_tests/deep_stack_uaf.cc (original)
+++ compiler-rt/trunk/lib/asan/lit_tests/deep_stack_uaf.cc Fri Dec 21 02:53:59 2012
@@ -25,7 +25,7 @@
};
int main() {
- char *x = new char[10];
+ char *x = (char*)malloc(10);
// deep_free(x);
DeepFree<200>::free(x);
return x[5];
Added: compiler-rt/trunk/lib/asan/lit_tests/malloc_delete_mismatch.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/lit_tests/malloc_delete_mismatch.cc?rev=170869&view=auto
==============================================================================
--- compiler-rt/trunk/lib/asan/lit_tests/malloc_delete_mismatch.cc (added)
+++ compiler-rt/trunk/lib/asan/lit_tests/malloc_delete_mismatch.cc Fri Dec 21 02:53:59 2012
@@ -0,0 +1,26 @@
+// Check that we detect malloc/delete mismatch only if the approptiate flag
+// is set.
+
+// RUN: %clangxx_asan -g %s -o %t 2>&1
+// RUN: ASAN_OPTIONS=alloc_dealloc_mismatch=1 %t 2>&1 | \
+// RUN: %symbolize | FileCheck %s
+
+// No error here.
+// RUN: ASAN_OPTIONS=alloc_dealloc_mismatch=0 %t
+#include <stdlib.h>
+
+static volatile char *x;
+
+int main() {
+ x = (char*)malloc(10);
+ x[0] = 0;
+ delete x;
+}
+// CHECK: ERROR: AddressSanitizer: alloc-dealloc-mismatch (malloc vs operator delete) on 0x
+// CHECK-NEXT: #0{{.*}}operator delete
+// CHECK-NEXT: #1{{.*}}main
+// CHECK: is located 0 bytes inside of 10-byte region
+// CHECK-NEXT: allocated by thread T0 here:
+// CHECK-NEXT: #0{{.*}}malloc
+// CHECK-NEXT: #1{{.*}}main
+// CHECK: HINT: if you don't care about these warnings you may set ASAN_OPTIONS=alloc_dealloc_mismatch=0
Modified: compiler-rt/trunk/lib/asan/tests/asan_noinst_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/tests/asan_noinst_test.cc?rev=170869&r1=170868&r2=170869&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/tests/asan_noinst_test.cc (original)
+++ compiler-rt/trunk/lib/asan/tests/asan_noinst_test.cc Fri Dec 21 02:53:59 2012
@@ -64,7 +64,7 @@
void *ptr = vec[idx];
vec[idx] = vec.back();
vec.pop_back();
- __asan::asan_free(ptr, &stack1);
+ __asan::asan_free(ptr, &stack1, __asan::FROM_MALLOC);
} else {
size_t size = my_rand(&seed) % 1000 + 1;
switch ((my_rand(&seed) % 128)) {
@@ -73,7 +73,8 @@
case 2: size += 4096; break;
}
size_t alignment = 1 << (my_rand(&seed) % 10 + 1);
- char *ptr = (char*)__asan::asan_memalign(alignment, size, &stack2);
+ char *ptr = (char*)__asan::asan_memalign(alignment, size,
+ &stack2, __asan::FROM_MALLOC);
vec.push_back(ptr);
ptr[0] = 0;
ptr[size-1] = 0;
@@ -81,7 +82,7 @@
}
}
for (size_t i = 0; i < vec.size(); i++)
- __asan::asan_free(vec[i], &stack3);
+ __asan::asan_free(vec[i], &stack3, __asan::FROM_MALLOC);
}
@@ -262,12 +263,12 @@
const int size = 32;
void *p = __asan::asan_malloc(size, &stack);
- __asan::asan_free(p, &stack);
+ __asan::asan_free(p, &stack, __asan::FROM_MALLOC);
size_t i;
size_t max_i = 1 << 30;
for (i = 0; i < max_i; i++) {
void *p1 = __asan::asan_malloc(size, &stack);
- __asan::asan_free(p1, &stack);
+ __asan::asan_free(p1, &stack, __asan::FROM_MALLOC);
if (p1 == p) break;
}
// fprintf(stderr, "i=%ld\n", i);
@@ -284,7 +285,7 @@
for (size_t i = 0; i < 1000; i++) {
void *p = __asan::asan_malloc(1 + (my_rand(&seed) % 4000), &stack);
- __asan::asan_free(p, &stack);
+ __asan::asan_free(p, &stack, __asan::FROM_MALLOC);
}
return NULL;
}
@@ -315,7 +316,7 @@
p[i] = __asan::asan_malloc(32, &stack);
}
for (size_t i = 0; i < kNumMallocs; i++) {
- __asan::asan_free(p[i], &stack);
+ __asan::asan_free(p[i], &stack, __asan::FROM_MALLOC);
}
}
return NULL;
Modified: compiler-rt/trunk/lib/asan/tests/asan_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/tests/asan_test.cc?rev=170869&r1=170868&r2=170869&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/tests/asan_test.cc (original)
+++ compiler-rt/trunk/lib/asan/tests/asan_test.cc Fri Dec 21 02:53:59 2012
@@ -1520,7 +1520,7 @@
EXPECT_DEATH(Atoi(array + 9), RightOOBReadMessage(0));
array[8] = '-';
Atoi(array);
- delete array;
+ free(array);
}
TEST(AddressSanitizer, AtoiAndFriendsOOBTest) {
@@ -1574,7 +1574,7 @@
EXPECT_EQ(array, endptr);
Strtol(array + 2, NULL, 0);
EXPECT_EQ(array, endptr);
- delete array;
+ free(array);
}
TEST(AddressSanitizer, StrtollOOBTest) {
@@ -1622,7 +1622,7 @@
"AddressSanitizer: heap-buffer-overflow"
".* is located 4 bytes to the right of 10-byte region");
close(fd);
- delete x;
+ delete [] x;
}
TEST(AddressSanitizer, pread64) {
@@ -1634,7 +1634,7 @@
"AddressSanitizer: heap-buffer-overflow"
".* is located 4 bytes to the right of 10-byte region");
close(fd);
- delete x;
+ delete [] x;
}
TEST(AddressSanitizer, read) {
@@ -1646,7 +1646,7 @@
"AddressSanitizer: heap-buffer-overflow"
".* is located 4 bytes to the right of 10-byte region");
close(fd);
- delete x;
+ delete [] x;
}
#endif // defined(__linux__) && !defined(ANDROID) && !defined(__ANDROID__)
@@ -1986,6 +1986,27 @@
Ident(NoAddressSafety)();
}
+static string MismatchStr(const string &str) {
+ return string("AddressSanitizer: alloc-dealloc-mismatch \\(") + str;
+}
+
+// This test is disabled until we enable alloc_dealloc_mismatch by default.
+// The feature is also tested by lit tests.
+TEST(AddressSanitizer, DISABLED_AllocDeallocMismatch) {
+ EXPECT_DEATH(free(Ident(new int)),
+ MismatchStr("operator new vs free"));
+ EXPECT_DEATH(free(Ident(new int[2])),
+ MismatchStr("operator new \\[\\] vs free"));
+ EXPECT_DEATH(delete (Ident(new int[2])),
+ MismatchStr("operator new \\[\\] vs operator delete"));
+ EXPECT_DEATH(delete (Ident((int*)malloc(2 * sizeof(int)))),
+ MismatchStr("malloc vs operator delete"));
+ EXPECT_DEATH(delete [] (Ident(new int)),
+ MismatchStr("operator new vs operator delete \\[\\]"));
+ EXPECT_DEATH(delete [] (Ident((int*)malloc(2 * sizeof(int)))),
+ MismatchStr("malloc vs operator delete \\[\\]"));
+}
+
// ------------------ demo tests; run each one-by-one -------------
// e.g. --gtest_filter=*DemoOOBLeftHigh --gtest_also_run_disabled_tests
TEST(AddressSanitizer, DISABLED_DemoThreadedTest) {
More information about the llvm-commits
mailing list