<div dir="ltr"><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Nov 18, 2013 at 6:02 PM, Kostya Serebryany <span dir="ltr"><<a href="mailto:kcc@google.com" target="_blank">kcc@google.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Author: kcc<br>
Date: Mon Nov 18 08:02:05 2013<br>
New Revision: 195011<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=195011&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=195011&view=rev</a><br>
Log:<br>
[asan] introduce __sanitizer_annotate_contiguous_container<br>
<br>
Added:<br>
    compiler-rt/trunk/lib/asan/lit_tests/TestCases/contiguous_container.cc<br>
Modified:<br>
    compiler-rt/trunk/include/sanitizer/common_interface_defs.h<br>
    compiler-rt/trunk/lib/asan/asan_poisoning.cc<br>
    compiler-rt/trunk/lib/sanitizer_common/sanitizer_internal_defs.h<br>
<br>
Modified: compiler-rt/trunk/include/sanitizer/common_interface_defs.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/include/sanitizer/common_interface_defs.h?rev=195011&r1=195010&r2=195011&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/include/sanitizer/common_interface_defs.h?rev=195011&r1=195010&r2=195011&view=diff</a><br>

==============================================================================<br>
--- compiler-rt/trunk/include/sanitizer/common_interface_defs.h (original)<br>
+++ compiler-rt/trunk/include/sanitizer/common_interface_defs.h Mon Nov 18 08:02:05 2013<br>
@@ -50,6 +50,30 @@ extern "C" {<br>
   // Record and dump coverage info.<br>
   void __sanitizer_cov_dump();<br>
<br>
+  // Annotate the current state of a contiguous container, such as<br>
+  // std::vector, std::string or similar.<br>
+  // A contiguous container is a container that keeps all of its elements<br>
+  // in a contiguous region of memory. The container owns the region of memory<br>
+  // [beg, end); the memory [beg, mid) is used to store the current elements<br>
+  // and the memory [mid, end) is reserved for future elements;<br>
+  // end <= mid <= end. For example, in "std::vector<> v"<br>
+  //   beg = &v[0];<br>
+  //   end = beg + v.capacity() * sizeof(v[0]);<br>
+  //   mid = beg + v.size()     * sizeof(v[0]);<br>
+  //<br>
+  // This annotation tells the Sanitizer tool about the current state of the<br>
+  // container so that the tool can report errors when memory from [mid, end)<br>
+  // is accessed. Insert this annotation into methods like push_back/pop_back.<br>
+  // Supply the old and the new values of mid (old_mid/new_mid).<br>
+  // In the initial state mid == end and so should be the final<br>
+  // state when the container is destroyed or when it reallocates the storage.<br>
+  //<br>
+  // Use with caution and don't use for anything other than vector-like classes.<br>
+  //<br>
+  // For AddressSanitizer, 'beg' should be 8-aligned.<br>
+  void __sanitizer_annotate_contiguous_container(void *beg, void *end,<br>
+                                                 void *old_mid, void *new_mid);<br></blockquote><div><br></div><div>Shouldn't all of these be const void* ?</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

+<br>
 #ifdef __cplusplus<br>
 }  // extern "C"<br>
 #endif<br>
<br>
Modified: compiler-rt/trunk/lib/asan/asan_poisoning.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_poisoning.cc?rev=195011&r1=195010&r2=195011&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_poisoning.cc?rev=195011&r1=195010&r2=195011&view=diff</a><br>

==============================================================================<br>
--- compiler-rt/trunk/lib/asan/asan_poisoning.cc (original)<br>
+++ compiler-rt/trunk/lib/asan/asan_poisoning.cc Mon Nov 18 08:02:05 2013<br>
@@ -255,3 +255,45 @@ void __asan_unpoison_stack_memory(uptr a<br>
     Report("unpoisoning: %p %zx\n", (void*)addr, size);<br>
   PoisonAlignedStackMemory(addr, size, false);<br>
 }<br>
+<br>
+void __sanitizer_annotate_contiguous_container(void *beg_p, void *end_p,<br>
+                                               void *old_mid_p,<br>
+                                               void *new_mid_p) {<br>
+  uptr beg = reinterpret_cast<uptr>(beg_p);<br>
+  uptr end= reinterpret_cast<uptr>(end_p);<br>
+  uptr old_mid = reinterpret_cast<uptr>(old_mid_p);<br>
+  uptr new_mid = reinterpret_cast<uptr>(new_mid_p);<br>
+  uptr granularity = SHADOW_GRANULARITY;<br>
+  CHECK(beg <= end && beg <= old_mid && beg <= new_mid && old_mid <= end &&<br>
+        new_mid <= end && IsAligned(beg, granularity));<br></blockquote><div><br></div><div>beg <= end is redundant.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

+  CHECK_LE(end - beg,<br>
+           FIRST_32_SECOND_64(1UL << 30, 1UL << 34)); // Sanity check.<br>
+<br>
+  uptr a = RoundDownTo(Min(old_mid, new_mid), granularity);<br>
+  uptr c = RoundUpTo(Max(old_mid, new_mid), granularity);<br>
+  uptr b = new_mid;<br>
+  uptr b1 = RoundDownTo(b, granularity);<br>
+  uptr b2 = RoundUpTo(b, granularity);<br>
+  uptr d = old_mid;<br>
+  uptr d1 = RoundDownTo(d, granularity);<br>
+  uptr d2 = RoundUpTo(d, granularity);<br></blockquote><div><br></div><div>why do you need "b" and "d"? Consider moving b1 and b2 to the place where they actually used first.</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

+  // Currently we should be in this state:<br>
+  // [a, d1) is good, [d2, c) is bad, [d1, d2) is partially good.<br>
+  // Make a quick sanity check that we are indeed in this state.<br>
+  if (d1 != d2)<br>
+    CHECK_EQ(*(u8*)MemToShadow(d1), d - d1);<br>
+  if (a + granularity <= d1)<br>
+    CHECK_EQ(*(u8*)MemToShadow(a), 0);<br>
+  if (d2 + granularity <= c && c <= end)<br>
+    CHECK_EQ(*(u8 *)MemToShadow(c - granularity), kAsanUserPoisonedMemoryMagic);<br>
+<br>
+  // New state:<br>
+  // [a, b1) is good, [b2, c) is bad, [b1, b2) is partially good.<br>
+  // FIXME: we may want to have a separate poison magic value.<br>
+  PoisonShadow(a, b1 - a, 0);<br>
+  PoisonShadow(b2, c - b2, kAsanUserPoisonedMemoryMagic);<br>
+  if (b1 != b2) {<br>
+    CHECK_EQ(b2 - b1, granularity);<br>
+    *(u8*)MemToShadow(b1) = b - b1;<br>
+  }<br>
+}<br>
<br>
Added: compiler-rt/trunk/lib/asan/lit_tests/TestCases/contiguous_container.cc<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/lit_tests/TestCases/contiguous_container.cc?rev=195011&view=auto" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/lit_tests/TestCases/contiguous_container.cc?rev=195011&view=auto</a><br>

==============================================================================<br>
--- compiler-rt/trunk/lib/asan/lit_tests/TestCases/contiguous_container.cc (added)<br>
+++ compiler-rt/trunk/lib/asan/lit_tests/TestCases/contiguous_container.cc Mon Nov 18 08:02:05 2013<br>
@@ -0,0 +1,47 @@<br>
+// RUN: %clangxx_asan -O %s -o %t && %t<br>
+//<br>
+// Test __sanitizer_annotate_contiguous_container.<br>
+<br>
+#include <stdlib.h><br>
+#include <stdio.h><br>
+#include <string.h><br>
+#include <assert.h><br>
+<br>
+extern "C" {<br>
+void __sanitizer_annotate_contiguous_container(void *beg, void *end,<br>
+                                               void *old_mid, void *new_mid);<br>
+bool __asan_address_is_poisoned(void *addr);<br>
+}  // extern "C"<br>
+<br>
+void TestContainer(size_t capacity) {<br>
+  char *beg = new char[capacity];<br>
+  char *end = beg + capacity;<br>
+  char *mid = beg + capacity;<br>
+  char *old_mid = 0;<br>
+  unsigned seed = 0;<br>
+<br>
+  for (int i = 0; i < 10000; i++) {<br>
+    size_t size = rand_r(&seed) % (capacity + 1);<br>
+    assert(size <= capacity);<br>
+    old_mid = mid;<br>
+    mid = beg + size;<br>
+    __sanitizer_annotate_contiguous_container(beg, end, old_mid, mid);<br>
+<br>
+    for (size_t idx = 0; idx < size; idx++)<br>
+        assert(!__asan_address_is_poisoned(beg + idx));<br>
+    for (size_t idx = size; idx < capacity; idx++)<br>
+        assert(__asan_address_is_poisoned(beg + idx));<br>
+  }<br>
+<br>
+  // Don't forget to unpoison the whole thing before destroing/reallocating.<br>
+  __sanitizer_annotate_contiguous_container(beg, end, mid, end);<br>
+  for (size_t idx = 0; idx < capacity; idx++)<br>
+    assert(!__asan_address_is_poisoned(beg + idx));<br>
+  delete[] beg;<br>
+}<br>
+<br>
+int main(int argc, char **argv) {<br>
+  int n = argc == 1 ? 128 : atoi(argv[1]);<br>
+  for (int i = 0; i <= n; i++)<br>
+    TestContainer(i);<br>
+}<br></blockquote><div><br></div><div><br></div><div>Can we have a true positive test (i.e. crash caused by __sanitizer_annotate_contiguous_container annotations)?</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

<br>
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_internal_defs.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_internal_defs.h?rev=195011&r1=195010&r2=195011&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_internal_defs.h?rev=195011&r1=195010&r2=195011&view=diff</a><br>

==============================================================================<br>
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_internal_defs.h (original)<br>
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_internal_defs.h Mon Nov 18 08:02:05 2013<br>
@@ -113,6 +113,9 @@ extern "C" {<br>
<br>
   SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_dump();<br>
   SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov(void *pc);<br>
+  SANITIZER_INTERFACE_ATTRIBUTE<br>
+  void __sanitizer_annotate_contiguous_container(void *beg, void *end,<br>
+                                                 void *old_mid, void *new_mid);<br>
 }  // extern "C"<br>
<br>
<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br><div>Alexey Samsonov, MSK</div>
</div></div>