[compiler-rt] r195011 - [asan] introduce __sanitizer_annotate_contiguous_container
Kostya Serebryany
kcc at google.com
Tue Nov 19 00:44:24 PST 2013
Thanks for comments, addressed all in r195117.
--kcc
On Mon, Nov 18, 2013 at 6:51 PM, Alexey Samsonov <samsonov at google.com>wrote:
>
> 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/20131119/2870e22e/attachment.html>
More information about the llvm-commits
mailing list