[compiler-rt] r220013 - [asan] the run-time part of intra-object-overflow detector (-fsanitize-address-field-padding=1). Note that all of this is still experimental; don't use unless you are brave.

Kostya Serebryany kcc at google.com
Thu Oct 16 18:22:38 PDT 2014


Author: kcc
Date: Thu Oct 16 20:22:37 2014
New Revision: 220013

URL: http://llvm.org/viewvc/llvm-project?rev=220013&view=rev
Log:
[asan] the run-time part of intra-object-overflow detector (-fsanitize-address-field-padding=1). Note that all of this is still experimental; don't use unless you are brave.

Added:
    compiler-rt/trunk/test/asan/TestCases/intra-object-overflow.cc
Modified:
    compiler-rt/trunk/lib/asan/asan_interface_internal.h
    compiler-rt/trunk/lib/asan/asan_internal.h
    compiler-rt/trunk/lib/asan/asan_poisoning.cc
    compiler-rt/trunk/lib/asan/asan_report.cc

Modified: compiler-rt/trunk/lib/asan/asan_interface_internal.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interface_internal.h?rev=220013&r1=220012&r2=220013&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_interface_internal.h (original)
+++ compiler-rt/trunk/lib/asan/asan_interface_internal.h Thu Oct 16 20:22:37 2014
@@ -173,6 +173,10 @@ extern "C" {
   void __asan_poison_cxx_array_cookie(uptr p);
   SANITIZER_INTERFACE_ATTRIBUTE
   uptr __asan_load_cxx_array_cookie(uptr *p);
+  SANITIZER_INTERFACE_ATTRIBUTE
+  void __asan_poison_intra_object_redzone(uptr p, uptr size);
+  SANITIZER_INTERFACE_ATTRIBUTE
+  void __asan_unpoison_intra_object_redzone(uptr p, uptr size);
 }  // extern "C"
 
 #endif  // ASAN_INTERFACE_INTERNAL_H

Modified: compiler-rt/trunk/lib/asan/asan_internal.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_internal.h?rev=220013&r1=220012&r2=220013&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_internal.h (original)
+++ compiler-rt/trunk/lib/asan/asan_internal.h Thu Oct 16 20:22:37 2014
@@ -135,6 +135,7 @@ const int kAsanStackUseAfterScopeMagic =
 const int kAsanGlobalRedzoneMagic = 0xf9;
 const int kAsanInternalHeapMagic = 0xfe;
 const int kAsanArrayCookieMagic = 0xac;
+const int kAsanIntraObjectRedzone = 0xbb;
 
 static const uptr kCurrentStackFrameMagic = 0x41B58AB3;
 static const uptr kRetiredStackFrameMagic = 0x45E0360E;

Modified: compiler-rt/trunk/lib/asan/asan_poisoning.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_poisoning.cc?rev=220013&r1=220012&r2=220013&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_poisoning.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_poisoning.cc Thu Oct 16 20:22:37 2014
@@ -61,6 +61,27 @@ void FlushUnneededASanShadowMemory(uptr
     FlushUnneededShadowMemory(shadow_beg, shadow_end - shadow_beg);
 }
 
+void AsanPoisonOrUnpoisonIntraObjectRedzone(uptr ptr, uptr size, bool poison) {
+  uptr end = ptr + size;
+  if (common_flags()->verbosity) {
+    Printf("__asan_%spoison_intra_object_redzone [%p,%p) %zd\n",
+           poison ? "" : "un", ptr, end, size);
+    if (common_flags()->verbosity >= 2)
+      PRINT_CURRENT_STACK();
+  }
+  CHECK(size);
+  CHECK_LE(size, 4096);
+  CHECK(IsAligned(end, SHADOW_GRANULARITY));
+  if (!IsAligned(ptr, SHADOW_GRANULARITY)) {
+    *(u8 *)MemToShadow(ptr) =
+        poison ? static_cast<u8>(ptr % SHADOW_GRANULARITY) : 0;
+    ptr |= SHADOW_GRANULARITY - 1;
+    ptr++;
+  }
+  for (; ptr < end; ptr += SHADOW_GRANULARITY)
+    *(u8*)MemToShadow(ptr) = poison ? kAsanIntraObjectRedzone : 0;
+}
+
 }  // namespace __asan
 
 // ---------------------- Interface ---------------- {{{1
@@ -375,6 +396,17 @@ int __sanitizer_verify_contiguous_contai
       return 0;
   return 1;
 }
+
+extern "C" SANITIZER_INTERFACE_ATTRIBUTE
+void __asan_poison_intra_object_redzone(uptr ptr, uptr size) {
+  AsanPoisonOrUnpoisonIntraObjectRedzone(ptr, size, true);
+}
+
+extern "C" SANITIZER_INTERFACE_ATTRIBUTE
+void __asan_unpoison_intra_object_redzone(uptr ptr, uptr size) {
+  AsanPoisonOrUnpoisonIntraObjectRedzone(ptr, size, false);
+}
+
 // --- Implementation of LSan-specific functions --- {{{1
 namespace __lsan {
 bool WordIsPoisoned(uptr addr) {

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=220013&r1=220012&r2=220013&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_report.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_report.cc Thu Oct 16 20:22:37 2014
@@ -94,6 +94,8 @@ class Decorator: public __sanitizer::San
         return Red();
       case kAsanInternalHeapMagic:
         return Yellow();
+      case kAsanIntraObjectRedzone:
+        return Yellow();
       default:
         return Default();
     }
@@ -168,6 +170,8 @@ static void PrintLegend(InternalScopedSt
                   kAsanContiguousContainerOOBMagic);
   PrintShadowByte(str, "  Array cookie:            ",
                   kAsanArrayCookieMagic);
+  PrintShadowByte(str, "  Intra object redzone:    ",
+                  kAsanIntraObjectRedzone);
   PrintShadowByte(str, "  ASan internal:           ", kAsanInternalHeapMagic);
 }
 
@@ -981,6 +985,9 @@ void __asan_report_error(uptr pc, uptr b
       case kAsanGlobalRedzoneMagic:
         bug_descr = "global-buffer-overflow";
         break;
+      case kAsanIntraObjectRedzone:
+        bug_descr = "intra-object-overflow";
+        break;
     }
   }
 

Added: compiler-rt/trunk/test/asan/TestCases/intra-object-overflow.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/intra-object-overflow.cc?rev=220013&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/intra-object-overflow.cc (added)
+++ compiler-rt/trunk/test/asan/TestCases/intra-object-overflow.cc Thu Oct 16 20:22:37 2014
@@ -0,0 +1,31 @@
+// RUN: %clangxx_asan -O0 -fsanitize-address-field-padding=1  %s -o %t
+// RUN: not %run %t 11 2>&1 | FileCheck %s
+// RUN: %run %t 10
+//
+// FIXME: fix 32-bits.
+// REQUIRES: asan-64-bits
+#include <stdio.h>
+#include <stdlib.h>
+class Foo {
+ public:
+  Foo() : pre1(1), pre2(2), post1(3), post2(4) {
+  }
+  virtual ~Foo() {
+  }
+  void set(int i, int val) { a[i] = val; }
+// CHECK: ERROR: AddressSanitizer: intra-object-overflow
+// CHECK: #0 {{.*}}Foo::set{{.*}}intra-object-overflow.cc:[[@LINE-2]]
+ private:
+  int pre1, pre2;
+  int a[11];
+  int post1, post2;
+};
+
+int main(int argc, char **argv) {
+  int idx = argc == 2 ? atoi(argv[1]) : 0;
+  Foo *foo = new Foo;
+  foo->set(idx, 42);
+// CHECK: #1 {{.*}}main{{.*}}intra-object-overflow.cc:[[@LINE-1]]
+// CHECK: is located 84 bytes inside of 128-byte region
+  delete foo;
+}





More information about the llvm-commits mailing list