Rebase.
[official-gcc.git] / gcc / testsuite / g++.dg / asan / asan_oob_test.cc
blob2361dc286d792f9377a6f4f05857a3748906686b
1 //===-- asan_oob_test.cc --------------------------------------------------===//
2 //
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
5 //
6 //===----------------------------------------------------------------------===//
7 //
8 // This file is a part of AddressSanitizer, an address sanity checker.
9 //
10 //===----------------------------------------------------------------------===//
11 #include "asan_test_utils.h"
13 NOINLINE void asan_write_sized_aligned(uint8_t *p, size_t size) {
14 EXPECT_EQ(0U, ((uintptr_t)p % size));
15 if (size == 1) asan_write((uint8_t*)p);
16 else if (size == 2) asan_write((uint16_t*)p);
17 else if (size == 4) asan_write((uint32_t*)p);
18 else if (size == 8) asan_write((uint64_t*)p);
21 template<typename T>
22 NOINLINE void oob_test(int size, int off) {
23 char *p = (char*)malloc_aaa(size);
24 // fprintf(stderr, "writing %d byte(s) into [%p,%p) with offset %d\n",
25 // sizeof(T), p, p + size, off);
26 asan_write((T*)(p + off));
27 free_aaa(p);
30 template<typename T>
31 void OOBTest() {
32 char expected_str[100];
33 for (int size = sizeof(T); size < 20; size += 5) {
34 for (int i = -5; i < 0; i++) {
35 const char *str =
36 "is located.*%d byte.*to the left";
37 sprintf(expected_str, str, abs(i));
38 EXPECT_DEATH(oob_test<T>(size, i), expected_str);
41 for (int i = 0; i < (int)(size - sizeof(T) + 1); i++)
42 oob_test<T>(size, i);
44 for (int i = size - sizeof(T) + 1; i <= (int)(size + 2 * sizeof(T)); i++) {
45 const char *str =
46 "is located.*%d byte.*to the right";
47 int off = i >= size ? (i - size) : 0;
48 // we don't catch unaligned partially OOB accesses.
49 if (i % sizeof(T)) continue;
50 sprintf(expected_str, str, off);
51 EXPECT_DEATH(oob_test<T>(size, i), expected_str);
55 EXPECT_DEATH(oob_test<T>(kLargeMalloc, -1),
56 "is located.*1 byte.*to the left");
57 EXPECT_DEATH(oob_test<T>(kLargeMalloc, kLargeMalloc),
58 "is located.*0 byte.*to the right");
61 // TODO(glider): the following tests are EXTREMELY slow on Darwin:
62 // AddressSanitizer.OOB_char (125503 ms)
63 // AddressSanitizer.OOB_int (126890 ms)
64 // AddressSanitizer.OOBRightTest (315605 ms)
65 // AddressSanitizer.SimpleStackTest (366559 ms)
67 TEST(AddressSanitizer, OOB_char) {
68 OOBTest<U1>();
71 TEST(AddressSanitizer, OOB_int) {
72 OOBTest<U4>();
75 TEST(AddressSanitizer, OOBRightTest) {
76 for (size_t access_size = 1; access_size <= 8; access_size *= 2) {
77 for (size_t alloc_size = 1; alloc_size <= 8; alloc_size++) {
78 for (size_t offset = 0; offset <= 8; offset += access_size) {
79 void *p = malloc(alloc_size);
80 // allocated: [p, p + alloc_size)
81 // accessed: [p + offset, p + offset + access_size)
82 uint8_t *addr = (uint8_t*)p + offset;
83 if (offset + access_size <= alloc_size) {
84 asan_write_sized_aligned(addr, access_size);
85 } else {
86 int outside_bytes = offset > alloc_size ? (offset - alloc_size) : 0;
87 const char *str =
88 "is located.%d *byte.*to the right";
89 char expected_str[100];
90 sprintf(expected_str, str, outside_bytes);
91 EXPECT_DEATH(asan_write_sized_aligned(addr, access_size),
92 expected_str);
94 free(p);
100 TEST(AddressSanitizer, LargeOOBRightTest) {
101 size_t large_power_of_two = 1 << 19;
102 for (size_t i = 16; i <= 256; i *= 2) {
103 size_t size = large_power_of_two - i;
104 char *p = Ident(new char[size]);
105 EXPECT_DEATH(p[size] = 0, "is located 0 bytes to the right");
106 delete [] p;
110 TEST(AddressSanitizer, DISABLED_DemoOOBLeftLow) {
111 oob_test<U1>(10, -1);
114 TEST(AddressSanitizer, DISABLED_DemoOOBLeftHigh) {
115 oob_test<U1>(kLargeMalloc, -1);
118 TEST(AddressSanitizer, DISABLED_DemoOOBRightLow) {
119 oob_test<U1>(10, 10);
122 TEST(AddressSanitizer, DISABLED_DemoOOBRightHigh) {
123 oob_test<U1>(kLargeMalloc, kLargeMalloc);