[compiler-rt] r195011 - [asan] introduce __sanitizer_annotate_contiguous_container

Alexey Samsonov samsonov at google.com
Mon Nov 18 06:51:59 PST 2013


On Mon, Nov 18, 2013 at 6:02 PM, Kostya Serebryany <kcc at google.com> wrote:

> Author: kcc
> Date: Mon Nov 18 08:02:05 2013
> New Revision: 195011
>
> URL: http://llvm.org/viewvc/llvm-project?rev=195011&view=rev
> Log:
> [asan] introduce __sanitizer_annotate_contiguous_container
>
> Added:
>     compiler-rt/trunk/lib/asan/lit_tests/TestCases/contiguous_container.cc
> 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
>
> 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=195011&r1=195010&r2=195011&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/include/sanitizer/common_interface_defs.h (original)
> +++ compiler-rt/trunk/include/sanitizer/common_interface_defs.h Mon Nov 18
> 08:02:05 2013
> @@ -50,6 +50,30 @@ extern "C" {
>    // Record and dump coverage info.
>    void __sanitizer_cov_dump();
>
> +  // Annotate the current state of a contiguous container, such as
> +  // std::vector, std::string or similar.
> +  // A contiguous container is a container that keeps all of its elements
> +  // in a contiguous region of memory. The container owns the region of
> memory
> +  // [beg, end); the memory [beg, mid) is used to store the current
> elements
> +  // and the memory [mid, end) is reserved for future elements;
> +  // end <= mid <= end. For example, in "std::vector<> v"
> +  //   beg = &v[0];
> +  //   end = beg + v.capacity() * sizeof(v[0]);
> +  //   mid = beg + v.size()     * sizeof(v[0]);
> +  //
> +  // This annotation tells the Sanitizer tool about the current state of
> the
> +  // container so that the tool can report errors when memory from [mid,
> end)
> +  // is accessed. Insert this annotation into methods like
> push_back/pop_back.
> +  // Supply the old and the new values of mid (old_mid/new_mid).
> +  // In the initial state mid == end and so should be the final
> +  // state when the container is destroyed or when it reallocates the
> storage.
> +  //
> +  // Use with caution and don't use for anything other than vector-like
> classes.
> +  //
> +  // For AddressSanitizer, 'beg' should be 8-aligned.
> +  void __sanitizer_annotate_contiguous_container(void *beg, void *end,
> +                                                 void *old_mid, void
> *new_mid);
>

Shouldn't all of these be const void* ?


> +
>  #ifdef __cplusplus
>  }  // extern "C"
>  #endif
>
> 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=195011&r1=195010&r2=195011&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/asan/asan_poisoning.cc (original)
> +++ compiler-rt/trunk/lib/asan/asan_poisoning.cc Mon Nov 18 08:02:05 2013
> @@ -255,3 +255,45 @@ void __asan_unpoison_stack_memory(uptr a
>      Report("unpoisoning: %p %zx\n", (void*)addr, size);
>    PoisonAlignedStackMemory(addr, size, false);
>  }
> +
> +void __sanitizer_annotate_contiguous_container(void *beg_p, void *end_p,
> +                                               void *old_mid_p,
> +                                               void *new_mid_p) {
> +  uptr beg = reinterpret_cast<uptr>(beg_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;
> +  CHECK(beg <= end && beg <= old_mid && beg <= new_mid && old_mid <= end
> &&
> +        new_mid <= end && IsAligned(beg, granularity));
>

beg <= end is redundant.


> +  CHECK_LE(end - beg,
> +           FIRST_32_SECOND_64(1UL << 30, 1UL << 34)); // Sanity check.
> +
> +  uptr a = RoundDownTo(Min(old_mid, new_mid), granularity);
> +  uptr c = RoundUpTo(Max(old_mid, new_mid), granularity);
> +  uptr b = new_mid;
> +  uptr b1 = RoundDownTo(b, granularity);
> +  uptr b2 = RoundUpTo(b, granularity);
> +  uptr d = old_mid;
> +  uptr d1 = RoundDownTo(d, granularity);
> +  uptr d2 = RoundUpTo(d, granularity);
>

why do you need "b" and "d"? Consider moving b1 and b2 to the place where
they actually used first.


> +  // Currently we should be in this state:
> +  // [a, d1) is good, [d2, c) is bad, [d1, d2) is partially good.
> +  // Make a quick sanity check that we are indeed in this state.
> +  if (d1 != d2)
> +    CHECK_EQ(*(u8*)MemToShadow(d1), d - d1);
> +  if (a + granularity <= d1)
> +    CHECK_EQ(*(u8*)MemToShadow(a), 0);
> +  if (d2 + granularity <= c && c <= end)
> +    CHECK_EQ(*(u8 *)MemToShadow(c - granularity),
> kAsanUserPoisonedMemoryMagic);
> +
> +  // New state:
> +  // [a, b1) is good, [b2, c) is bad, [b1, b2) is partially good.
> +  // FIXME: we may want to have a separate poison magic value.
> +  PoisonShadow(a, b1 - a, 0);
> +  PoisonShadow(b2, c - b2, kAsanUserPoisonedMemoryMagic);
> +  if (b1 != b2) {
> +    CHECK_EQ(b2 - b1, granularity);
> +    *(u8*)MemToShadow(b1) = b - b1;
> +  }
> +}
>
> Added:
> compiler-rt/trunk/lib/asan/lit_tests/TestCases/contiguous_container.cc
> URL:
> http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/lit_tests/TestCases/contiguous_container.cc?rev=195011&view=auto
>
> ==============================================================================
> --- compiler-rt/trunk/lib/asan/lit_tests/TestCases/contiguous_container.cc
> (added)
> +++ compiler-rt/trunk/lib/asan/lit_tests/TestCases/contiguous_container.cc
> Mon Nov 18 08:02:05 2013
> @@ -0,0 +1,47 @@
> +// RUN: %clangxx_asan -O %s -o %t && %t
> +//
> +// Test __sanitizer_annotate_contiguous_container.
> +
> +#include <stdlib.h>
> +#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"
> +
> +void TestContainer(size_t capacity) {
> +  char *beg = new char[capacity];
> +  char *end = beg + capacity;
> +  char *mid = beg + capacity;
> +  char *old_mid = 0;
> +  unsigned seed = 0;
> +
> +  for (int i = 0; i < 10000; i++) {
> +    size_t size = rand_r(&seed) % (capacity + 1);
> +    assert(size <= capacity);
> +    old_mid = mid;
> +    mid = beg + size;
> +    __sanitizer_annotate_contiguous_container(beg, end, old_mid, mid);
> +
> +    for (size_t idx = 0; idx < size; idx++)
> +        assert(!__asan_address_is_poisoned(beg + idx));
> +    for (size_t idx = size; idx < capacity; idx++)
> +        assert(__asan_address_is_poisoned(beg + idx));
> +  }
> +
> +  // Don't forget to unpoison the whole thing before
> destroing/reallocating.
> +  __sanitizer_annotate_contiguous_container(beg, end, mid, end);
> +  for (size_t idx = 0; idx < capacity; idx++)
> +    assert(!__asan_address_is_poisoned(beg + idx));
> +  delete[] beg;
> +}
> +
> +int main(int argc, char **argv) {
> +  int n = argc == 1 ? 128 : atoi(argv[1]);
> +  for (int i = 0; i <= n; i++)
> +    TestContainer(i);
> +}
>


Can we have a true positive test (i.e. crash caused by
__sanitizer_annotate_contiguous_container annotations)?


>
> 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=195011&r1=195010&r2=195011&view=diff
>
> ==============================================================================
> --- compiler-rt/trunk/lib/sanitizer_common/sanitizer_internal_defs.h
> (original)
> +++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_internal_defs.h Mon
> Nov 18 08:02:05 2013
> @@ -113,6 +113,9 @@ extern "C" {
>
>    SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_dump();
>    SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov(void *pc);
> +  SANITIZER_INTERFACE_ATTRIBUTE
> +  void __sanitizer_annotate_contiguous_container(void *beg, void *end,
> +                                                 void *old_mid, void
> *new_mid);
>  }  // extern "C"
>
>
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
>



-- 
Alexey Samsonov, MSK
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131118/5e908a0d/attachment.html>


More information about the llvm-commits mailing list