[compiler-rt] r190781 - [msan] Fix origin of deallocated memory.
Evgeniy Stepanov
eugeni.stepanov at gmail.com
Mon Sep 16 04:03:31 PDT 2013
Author: eugenis
Date: Mon Sep 16 06:03:31 2013
New Revision: 190781
URL: http://llvm.org/viewvc/llvm-project?rev=190781&view=rev
Log:
[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.
Added:
compiler-rt/trunk/lib/msan/lit_tests/use-after-free.cc (with props)
Modified:
compiler-rt/trunk/lib/msan/msan.cc
compiler-rt/trunk/lib/msan/msan.h
compiler-rt/trunk/lib/msan/msan_allocator.cc
compiler-rt/trunk/lib/msan/msan_flags.h
compiler-rt/trunk/lib/msan/msan_interceptors.cc
compiler-rt/trunk/lib/msan/msan_new_delete.cc
Added: compiler-rt/trunk/lib/msan/lit_tests/use-after-free.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/lit_tests/use-after-free.cc?rev=190781&view=auto
==============================================================================
--- compiler-rt/trunk/lib/msan/lit_tests/use-after-free.cc (added)
+++ compiler-rt/trunk/lib/msan/lit_tests/use-after-free.cc Mon Sep 16 06:03:31 2013
@@ -0,0 +1,34 @@
+// RUN: %clangxx_msan -m64 -O0 %s -o %t && not %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out
+// RUN: %clangxx_msan -m64 -O1 %s -o %t && not %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out
+// RUN: %clangxx_msan -m64 -O2 %s -o %t && not %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out
+// RUN: %clangxx_msan -m64 -O3 %s -o %t && not %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out
+
+// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O0 %s -o %t && not %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out
+// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O1 %s -o %t && not %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out
+// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O2 %s -o %t && not %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out
+// RUN: %clangxx_msan -fsanitize-memory-track-origins -m64 -O3 %s -o %t && not %t >%t.out 2>&1
+// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-ORIGINS < %t.out
+
+#include <stdlib.h>
+int main(int argc, char **argv) {
+ int *volatile p = (int *)malloc(sizeof(int));
+ *p = 42;
+ free(p);
+
+ if (*p)
+ exit(0);
+ // CHECK: WARNING: MemorySanitizer: use-of-uninitialized-value
+ // CHECK: {{#0 0x.* in main .*use-after-free.cc:}}[[@LINE-3]]
+
+ // CHECK-ORIGINS: Uninitialized value was created by a heap allocation
+ // CHECK-ORIGINS: {{#0 0x.* in .*free}}
+ // CHECK-ORIGINS: {{#1 0x.* in main .*use-after-free.cc:}}[[@LINE-9]]
+ return 0;
+}
Propchange: compiler-rt/trunk/lib/msan/lit_tests/use-after-free.cc
------------------------------------------------------------------------------
svn:eol-style = LF
Modified: compiler-rt/trunk/lib/msan/msan.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan.cc?rev=190781&r1=190780&r2=190781&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan.cc (original)
+++ compiler-rt/trunk/lib/msan/msan.cc Mon Sep 16 06:03:31 2013
@@ -122,6 +122,7 @@ static void ParseFlagsFromString(Flags *
ParseFlag(str, &f->poison_heap_with_zeroes, "poison_heap_with_zeroes");
ParseFlag(str, &f->poison_stack_with_zeroes, "poison_stack_with_zeroes");
ParseFlag(str, &f->poison_in_malloc, "poison_in_malloc");
+ ParseFlag(str, &f->poison_in_malloc, "poison_in_free");
ParseFlag(str, &f->exit_code, "exit_code");
if (f->exit_code < 0 || f->exit_code > 127) {
Printf("Exit code not in [0, 128) range: %d\n", f->exit_code);
@@ -153,6 +154,7 @@ static void InitializeFlags(Flags *f, co
f->poison_heap_with_zeroes = false;
f->poison_stack_with_zeroes = false;
f->poison_in_malloc = true;
+ f->poison_in_free = true;
f->exit_code = 77;
f->report_umrs = true;
f->verbosity = 0;
Modified: compiler-rt/trunk/lib/msan/msan.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan.h?rev=190781&r1=190780&r2=190781&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan.h (original)
+++ compiler-rt/trunk/lib/msan/msan.h Mon Sep 16 06:03:31 2013
@@ -46,7 +46,7 @@ void InitializeInterceptors();
void *MsanReallocate(StackTrace *stack, void *oldp, uptr size,
uptr alignment, bool zeroise);
-void MsanDeallocate(void *ptr);
+void MsanDeallocate(StackTrace *stack, void *ptr);
void InstallTrapHandler();
void InstallAtExitHandler();
void ReplaceOperatorsNewAndDelete();
Modified: compiler-rt/trunk/lib/msan/msan_allocator.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan_allocator.cc?rev=190781&r1=190780&r2=190781&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan_allocator.cc (original)
+++ compiler-rt/trunk/lib/msan/msan_allocator.cc Mon Sep 16 06:03:31 2013
@@ -51,21 +51,23 @@ static void *MsanAllocate(StackTrace *st
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,
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,
// 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;
}
Modified: compiler-rt/trunk/lib/msan/msan_flags.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan_flags.h?rev=190781&r1=190780&r2=190781&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan_flags.h (original)
+++ compiler-rt/trunk/lib/msan/msan_flags.h Mon Sep 16 06:03:31 2013
@@ -23,6 +23,7 @@ struct Flags {
bool poison_heap_with_zeroes; // default: false
bool poison_stack_with_zeroes; // default: false
bool poison_in_malloc; // default: true
+ bool poison_in_free; // default: true
bool report_umrs;
bool wrap_signals;
bool halt_on_error;
Modified: compiler-rt/trunk/lib/msan/msan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan_interceptors.cc?rev=190781&r1=190780&r2=190781&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/msan/msan_interceptors.cc Mon Sep 16 06:03:31 2013
@@ -165,9 +165,9 @@ INTERCEPTOR(void *, pvalloc, SIZE_T size
}
INTERCEPTOR(void, free, void *ptr) {
- ENSURE_MSAN_INITED();
+ GET_MALLOC_STACK_TRACE;
if (ptr == 0) return;
- MsanDeallocate(ptr);
+ MsanDeallocate(&stack, ptr);
}
INTERCEPTOR(SIZE_T, strlen, const char *s) {
Modified: compiler-rt/trunk/lib/msan/msan_new_delete.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan_new_delete.cc?rev=190781&r1=190780&r2=190781&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan_new_delete.cc (original)
+++ compiler-rt/trunk/lib/msan/msan_new_delete.cc Mon Sep 16 06:03:31 2013
@@ -43,7 +43,8 @@ void *operator new(size_t size, std::not
void *operator new[](size_t size, std::nothrow_t const&) { OPERATOR_NEW_BODY; }
#define OPERATOR_DELETE_BODY \
- if (ptr) MsanDeallocate(ptr)
+ GET_MALLOC_STACK_TRACE; \
+ if (ptr) MsanDeallocate(&stack, ptr)
void operator delete(void *ptr) { OPERATOR_DELETE_BODY; }
void operator delete[](void *ptr) { OPERATOR_DELETE_BODY; }
More information about the llvm-commits
mailing list