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