[compiler-rt] r340591 - [hwasan] implement detection of double-free (invalid-free)
Kostya Serebryany via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 23 18:12:26 PDT 2018
Author: kcc
Date: Thu Aug 23 18:12:26 2018
New Revision: 340591
URL: http://llvm.org/viewvc/llvm-project?rev=340591&view=rev
Log:
[hwasan] implement detection of double-free (invalid-free)
Added:
compiler-rt/trunk/test/hwasan/TestCases/double-free.c
Modified:
compiler-rt/trunk/lib/hwasan/hwasan_allocator.cc
compiler-rt/trunk/lib/hwasan/hwasan_report.cc
compiler-rt/trunk/lib/hwasan/hwasan_report.h
Modified: compiler-rt/trunk/lib/hwasan/hwasan_allocator.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_allocator.cc?rev=340591&r1=340590&r2=340591&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_allocator.cc (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_allocator.cc Thu Aug 23 18:12:26 2018
@@ -24,6 +24,7 @@
#include "hwasan_mapping.h"
#include "hwasan_thread.h"
#include "hwasan_poisoning.h"
+#include "hwasan_report.h"
namespace __hwasan {
@@ -173,11 +174,21 @@ static void *HwasanAllocate(StackTrace *
return user_ptr;
}
+static bool PointerAndMemoryTagsMatch(void *user_ptr) {
+ CHECK(user_ptr);
+ tag_t ptr_tag = GetTagFromPointer(reinterpret_cast<uptr>(user_ptr));
+ tag_t mem_tag = *reinterpret_cast<tag_t *>(
+ MEM_TO_SHADOW(GetAddressFromPointer(user_ptr)));
+ return ptr_tag == mem_tag;
+}
+
void HwasanDeallocate(StackTrace *stack, void *user_ptr) {
CHECK(user_ptr);
HWASAN_FREE_HOOK(user_ptr);
void *p = GetAddressFromPointer(user_ptr);
+ if (!PointerAndMemoryTagsMatch(user_ptr))
+ ReportInvalidFree(stack, reinterpret_cast<uptr>(user_ptr));
Metadata *meta = reinterpret_cast<Metadata *>(allocator.GetMetaData(p));
uptr size = meta->requested_size;
meta->state = CHUNK_FREE;
@@ -226,7 +237,7 @@ void *HwasanReallocate(StackTrace *stack
t ? t->GenerateRandomTag() : kFallbackAllocTag);
}
if (new_size > old_size) {
- tag_t tag = GetTagFromPointer((uptr)user_old_p);
+ tag_t tag = GetTagFromPointer(reinterpret_cast<uptr>(user_old_p));
TagMemoryAligned((uptr)old_p + old_size, new_size - old_size, tag);
}
return user_old_p;
Modified: compiler-rt/trunk/lib/hwasan/hwasan_report.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_report.cc?rev=340591&r1=340590&r2=340591&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_report.cc (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_report.cc Thu Aug 23 18:12:26 2018
@@ -109,6 +109,54 @@ void ReportInvalidAccessInsideAddressRan
// DescribeMemoryRange(start, size);
}
+static void PrintTagsAroundAddr(tag_t *tag_ptr) {
+ Printf(
+ "Memory tags around the buggy address (one tag corresponds to %zd "
+ "bytes):\n", kShadowAlignment);
+
+ const uptr row_len = 16; // better be power of two.
+ const uptr num_rows = 11;
+ tag_t *center_row_beg = reinterpret_cast<tag_t *>(
+ RoundDownTo(reinterpret_cast<uptr>(tag_ptr), row_len));
+ tag_t *beg_row = center_row_beg - row_len * (num_rows / 2);
+ tag_t *end_row = center_row_beg + row_len * (num_rows / 2);
+ for (tag_t *row = beg_row; row < end_row; row += row_len) {
+ Printf("%s", row == center_row_beg ? "=>" : " ");
+ for (uptr i = 0; i < row_len; i++) {
+ Printf("%s", row + i == tag_ptr ? "[" : " ");
+ Printf("%02x", row[i]);
+ Printf("%s", row + i == tag_ptr ? "]" : " ");
+ }
+ Printf("%s\n", row == center_row_beg ? "<=" : " ");
+ }
+}
+
+void ReportInvalidFree(StackTrace *stack, uptr addr) {
+ ScopedErrorReportLock l;
+ uptr address = GetAddressFromPointer(addr);
+ tag_t ptr_tag = GetTagFromPointer(addr);
+ tag_t *tag_ptr = reinterpret_cast<tag_t*>(MEM_TO_SHADOW(address));
+ tag_t mem_tag = *tag_ptr;
+ Decorator d;
+ Printf("%s", d.Error());
+ uptr pc = stack->size ? stack->trace[0] : 0;
+ const char *bug_type = "invalid-free";
+ Report("ERROR: %s: %s on address %p at pc %p\n", SanitizerToolName, bug_type,
+ address, pc);
+ Printf("%s", d.Access());
+ Printf("tags: %02x/%02x (ptr/mem)\n", ptr_tag, mem_tag);
+ Printf("%s", d.Default());
+
+ stack->Print();
+
+ PrintAddressDescription(address, 0);
+
+ PrintTagsAroundAddr(tag_ptr);
+
+ ReportErrorSummary(bug_type, stack);
+ Die();
+}
+
void ReportTagMismatch(StackTrace *stack, uptr addr, uptr access_size,
bool is_store) {
ScopedErrorReportLock l;
@@ -119,7 +167,8 @@ void ReportTagMismatch(StackTrace *stack
// TODO: when possible, try to print heap-use-after-free, etc.
const char *bug_type = "tag-mismatch";
uptr pc = stack->size ? stack->trace[0] : 0;
- Report("ERROR: %s: %s on address %p at pc %p\n", SanitizerToolName, bug_type, address, pc);
+ Report("ERROR: %s: %s on address %p at pc %p\n", SanitizerToolName, bug_type,
+ address, pc);
tag_t ptr_tag = GetTagFromPointer(addr);
tag_t *tag_ptr = reinterpret_cast<tag_t*>(MEM_TO_SHADOW(address));
@@ -133,25 +182,7 @@ void ReportTagMismatch(StackTrace *stack
PrintAddressDescription(address, access_size);
- Printf(
- "Memory tags around the buggy address (one tag corresponds to %zd "
- "bytes):\n", kShadowAlignment);
-
- const uptr row_len = 16; // better be power of two.
- const uptr num_rows = 11;
- tag_t *center_row_beg = reinterpret_cast<tag_t *>(
- RoundDownTo(reinterpret_cast<uptr>(tag_ptr), row_len));
- tag_t *beg_row = center_row_beg - row_len * (num_rows / 2);
- tag_t *end_row = center_row_beg + row_len * (num_rows / 2);
- for (tag_t *row = beg_row; row < end_row; row += row_len) {
- Printf("%s", row == center_row_beg ? "=>" : " ");
- for (uptr i = 0; i < row_len; i++) {
- Printf("%s", row + i == tag_ptr ? "[" : " ");
- Printf("%02x", row[i]);
- Printf("%s", row + i == tag_ptr ? "]" : " ");
- }
- Printf("%s\n", row == center_row_beg ? "<=" : " ");
- }
+ PrintTagsAroundAddr(tag_ptr);
ReportErrorSummary(bug_type, stack);
}
Modified: compiler-rt/trunk/lib/hwasan/hwasan_report.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_report.h?rev=340591&r1=340590&r2=340591&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_report.h (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_report.h Thu Aug 23 18:12:26 2018
@@ -27,6 +27,7 @@ void ReportInvalidAccessInsideAddressRan
uptr size, uptr offset);
void ReportTagMismatch(StackTrace *stack, uptr addr, uptr access_size,
bool is_store);
+void ReportInvalidFree(StackTrace *stack, uptr addr);
void ReportAtExitStatistics();
Added: compiler-rt/trunk/test/hwasan/TestCases/double-free.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/hwasan/TestCases/double-free.c?rev=340591&view=auto
==============================================================================
--- compiler-rt/trunk/test/hwasan/TestCases/double-free.c (added)
+++ compiler-rt/trunk/test/hwasan/TestCases/double-free.c Thu Aug 23 18:12:26 2018
@@ -0,0 +1,23 @@
+// RUN: %clang_hwasan %s -o %t && not %run %t 2>&1 | FileCheck %s
+
+// REQUIRES: stable-runtime
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <sanitizer/hwasan_interface.h>
+
+int main() {
+ __hwasan_enable_allocator_tagging();
+ char * volatile x = (char*)malloc(40);
+ free(x);
+ free(x);
+// CHECK: ERROR: HWAddressSanitizer: invalid-free on address
+// CHECK: tags: [[PTR_TAG:..]]/[[MEM_TAG:..]] (ptr/mem)
+// CHECK: freed here:
+// CHECK: previously allocated here:
+// CHECK: Memory tags around the buggy address (one tag corresponds to 16 bytes):
+// CHECK: =>{{.*}}[[MEM_TAG]]
+ fprintf(stderr, "DONE\n");
+ __hwasan_disable_allocator_tagging();
+// CHECK-NOT: DONE
+}
More information about the llvm-commits
mailing list