diff options
author | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2013-09-16 11:03:31 +0000 |
---|---|---|
committer | Evgeniy Stepanov <eugeni.stepanov@gmail.com> | 2013-09-16 11:03:31 +0000 |
commit | effdc7e483708cfa4dc597c21f246c5dbc09daa0 (patch) | |
tree | d24a8dd8d1b4a1ff815ae426f8e82187064010bf /lib/msan/msan_allocator.cc | |
parent | 1effc056910803fd8213ac940e9d17f3c0160b4b (diff) |
[msan] Fix origin of deallocated memory.
MSan poisons deallocated memory but it used to give it an invalid origin value,
resulting in confusing reports. This change associates deallocation stack trace
with such memory.
Note that MSan does not have quarantine, and use-after-free detection is very
limited.
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@190781 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/msan/msan_allocator.cc')
-rw-r--r-- | lib/msan/msan_allocator.cc | 35 |
1 files changed, 22 insertions, 13 deletions
diff --git a/lib/msan/msan_allocator.cc b/lib/msan/msan_allocator.cc index 050a55c50..0fe1297a8 100644 --- a/lib/msan/msan_allocator.cc +++ b/lib/msan/msan_allocator.cc @@ -51,21 +51,23 @@ static void *MsanAllocate(StackTrace *stack, uptr size, void *res = allocator.Allocate(&cache, size, alignment, false); Metadata *meta = reinterpret_cast<Metadata*>(allocator.GetMetaData(res)); meta->requested_size = size; - if (zeroise) + if (zeroise) { __msan_clear_and_unpoison(res, size); - else if (flags()->poison_in_malloc) + } else if (flags()->poison_in_malloc) { __msan_poison(res, size); - if (__msan_get_track_origins()) { - u32 stack_id = StackDepotPut(stack->trace, stack->size); - CHECK(stack_id); - CHECK_EQ((stack_id >> 31), 0); // Higher bit is occupied by stack origins. - __msan_set_origin(res, size, stack_id); + if (__msan_get_track_origins()) { + u32 stack_id = StackDepotPut(stack->trace, stack->size); + CHECK(stack_id); + CHECK_EQ((stack_id >> 31), + 0); // Higher bit is occupied by stack origins. + __msan_set_origin(res, size, stack_id); + } } MSAN_MALLOC_HOOK(res, size); return res; } -void MsanDeallocate(void *p) { +void MsanDeallocate(StackTrace *stack, void *p) { CHECK(p); Init(); MSAN_FREE_HOOK(p); @@ -74,9 +76,16 @@ void MsanDeallocate(void *p) { meta->requested_size = 0; // This memory will not be reused by anyone else, so we are free to keep it // poisoned. - __msan_poison(p, size); - if (__msan_get_track_origins()) - __msan_set_origin(p, size, -1); + if (flags()->poison_in_free) { + __msan_poison(p, size); + if (__msan_get_track_origins()) { + u32 stack_id = StackDepotPut(stack->trace, stack->size); + CHECK(stack_id); + CHECK_EQ((stack_id >> 31), + 0); // Higher bit is occupied by stack origins. + __msan_set_origin(p, size, stack_id); + } + } allocator.Deallocate(&cache, p); } @@ -85,7 +94,7 @@ void *MsanReallocate(StackTrace *stack, void *old_p, uptr new_size, if (!old_p) return MsanAllocate(stack, new_size, alignment, zeroise); if (!new_size) { - MsanDeallocate(old_p); + MsanDeallocate(stack, old_p); return 0; } Metadata *meta = reinterpret_cast<Metadata*>(allocator.GetMetaData(old_p)); @@ -103,7 +112,7 @@ void *MsanReallocate(StackTrace *stack, void *old_p, uptr new_size, // Printf("realloc: old_size %zd new_size %zd\n", old_size, new_size); if (new_p) __msan_memcpy(new_p, old_p, memcpy_size); - MsanDeallocate(old_p); + MsanDeallocate(stack, old_p); return new_p; } |