[compiler-rt] r208092 - [asan] introduce interface function __sanitizer_verify_contiguous_container to verify annotations in vector-like containers

Kostya Serebryany kcc at google.com
Tue May 6 07:41:02 PDT 2014


Author: kcc
Date: Tue May  6 09:41:01 2014
New Revision: 208092

URL: http://llvm.org/viewvc/llvm-project?rev=208092&view=rev
Log:
[asan] introduce interface function __sanitizer_verify_contiguous_container to verify annotations in vector-like containers

Modified:
    compiler-rt/trunk/include/sanitizer/common_interface_defs.h
    compiler-rt/trunk/lib/asan/asan_poisoning.cc
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_internal_defs.h
    compiler-rt/trunk/test/asan/TestCases/contiguous_container.cc

Modified: compiler-rt/trunk/include/sanitizer/common_interface_defs.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/include/sanitizer/common_interface_defs.h?rev=208092&r1=208091&r2=208092&view=diff
==============================================================================
--- compiler-rt/trunk/include/sanitizer/common_interface_defs.h (original)
+++ compiler-rt/trunk/include/sanitizer/common_interface_defs.h Tue May  6 09:41:01 2014
@@ -86,6 +86,14 @@ extern "C" {
                                                  const void *end,
                                                  const void *old_mid,
                                                  const void *new_mid);
+  // Returns true if the contiguous container [beg, end) ir properly poisoned
+  // (e.g. with __sanitizer_annotate_contiguous_container), i.e. if
+  //  - [beg, mid) is addressable,
+  //  - [mid, end) is unaddressable.
+  // Full verification requires O(end-beg) time; this function tries to avoid
+  // such complexity by touching only parts of the container around beg/mid/end.
+  int __sanitizer_verify_contiguous_container(const void *beg, const void *mid,
+                                              const void *end);
 
   // Print the stack trace leading to this call. Useful for debugging user code.
   void __sanitizer_print_stack_trace();

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=208092&r1=208091&r2=208092&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_poisoning.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_poisoning.cc Tue May  6 09:41:01 2014
@@ -270,7 +270,7 @@ void __sanitizer_annotate_contiguous_con
   VPrintf(2, "contiguous_container: %p %p %p %p\n", beg_p, end_p, old_mid_p,
           new_mid_p);
   uptr beg = reinterpret_cast<uptr>(beg_p);
-  uptr end= reinterpret_cast<uptr>(end_p);
+  uptr end = reinterpret_cast<uptr>(end_p);
   uptr old_mid = reinterpret_cast<uptr>(old_mid_p);
   uptr new_mid = reinterpret_cast<uptr>(new_mid_p);
   uptr granularity = SHADOW_GRANULARITY;
@@ -313,6 +313,38 @@ void __sanitizer_annotate_contiguous_con
   }
 }
 
+int __sanitizer_verify_contiguous_container(const void *beg_p,
+                                            const void *mid_p,
+                                            const void *end_p) {
+  if (!flags()->detect_container_overflow) return 1;
+  uptr beg = reinterpret_cast<uptr>(beg_p);
+  uptr end = reinterpret_cast<uptr>(end_p);
+  uptr mid = reinterpret_cast<uptr>(mid_p);
+  CHECK_LE(beg, mid);
+  CHECK_LE(mid, end);
+  // Check some bytes starting from beg, some bytes around mid, and some bytes
+  // ending with end.
+  uptr kMaxRangeToCheck = 32;
+  uptr r1_beg = beg;
+  uptr r1_end = Min(end + kMaxRangeToCheck, mid);
+  uptr r2_beg = Max(beg, mid - kMaxRangeToCheck);
+  uptr r2_end = Min(end, mid + kMaxRangeToCheck);
+  uptr r3_beg = Max(end - kMaxRangeToCheck, mid);
+  uptr r3_end = end;
+  for (uptr i = r1_beg; i < r1_end; i++)
+    if (AddressIsPoisoned(i))
+      return 0;
+  for (uptr i = r2_beg; i < mid; i++)
+    if (AddressIsPoisoned(i))
+      return 0;
+  for (uptr i = mid; i < r2_end; i++)
+    if (!AddressIsPoisoned(i))
+      return 0;
+  for (uptr i = r3_beg; i < r3_end; i++)
+    if (!AddressIsPoisoned(i))
+      return 0;
+  return 1;
+}
 // --- Implementation of LSan-specific functions --- {{{1
 namespace __lsan {
 bool WordIsPoisoned(uptr addr) {

Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_internal_defs.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_internal_defs.h?rev=208092&r1=208091&r2=208092&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_internal_defs.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_internal_defs.h Tue May  6 09:41:01 2014
@@ -111,6 +111,9 @@ extern "C" {
                                                  const void *end,
                                                  const void *old_mid,
                                                  const void *new_mid);
+  SANITIZER_INTERFACE_ATTRIBUTE
+  int __sanitizer_verify_contiguous_container(const void *beg, const void *mid,
+                                              const void *end);
 }  // extern "C"
 
 

Modified: compiler-rt/trunk/test/asan/TestCases/contiguous_container.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/contiguous_container.cc?rev=208092&r1=208091&r2=208092&view=diff
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/contiguous_container.cc (original)
+++ compiler-rt/trunk/test/asan/TestCases/contiguous_container.cc Tue May  6 09:41:01 2014
@@ -6,12 +6,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <assert.h>
-
-extern "C" {
-void __sanitizer_annotate_contiguous_container(void *beg, void *end,
-                                               void *old_mid, void *new_mid);
-bool __asan_address_is_poisoned(void *addr);
-}  // extern "C"
+#include <sanitizer/asan_interface.h>
 
 void TestContainer(size_t capacity) {
   char *beg = new char[capacity];
@@ -30,6 +25,11 @@ void TestContainer(size_t capacity) {
         assert(!__asan_address_is_poisoned(beg + idx));
     for (size_t idx = size; idx < capacity; idx++)
         assert(__asan_address_is_poisoned(beg + idx));
+    assert(__sanitizer_verify_contiguous_container(beg, mid, end));
+    if (mid != beg)
+      assert(!__sanitizer_verify_contiguous_container(beg, mid - 1, end));
+    if (mid != end)
+      assert(!__sanitizer_verify_contiguous_container(beg, mid + 1, end));
   }
 
   // Don't forget to unpoison the whole thing before destroing/reallocating.





More information about the llvm-commits mailing list