Home | History | Annotate | Line # | Download | only in tests
      1 //===-- asan_mem_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 #include <vector>
     15 
     16 template<typename T>
     17 void MemSetOOBTestTemplate(size_t length) {
     18   if (length == 0) return;
     19   size_t size = Ident(sizeof(T) * length);
     20   T *array = Ident((T*)malloc(size));
     21   int element = Ident(42);
     22   int zero = Ident(0);
     23   void *(*MEMSET)(void *s, int c, size_t n) = Ident(memset);
     24   // memset interval inside array
     25   MEMSET(array, element, size);
     26   MEMSET(array, element, size - 1);
     27   MEMSET(array + length - 1, element, sizeof(T));
     28   MEMSET(array, element, 1);
     29 
     30   // memset 0 bytes
     31   MEMSET(array - 10, element, zero);
     32   MEMSET(array - 1, element, zero);
     33   MEMSET(array, element, zero);
     34   MEMSET(array + length, 0, zero);
     35   MEMSET(array + length + 1, 0, zero);
     36 
     37   // try to memset bytes to the right of array
     38   EXPECT_DEATH(MEMSET(array, 0, size + 1),
     39                RightOOBWriteMessage(0));
     40   EXPECT_DEATH(MEMSET((char*)(array + length) - 1, element, 6),
     41                RightOOBWriteMessage(0));
     42   EXPECT_DEATH(MEMSET(array + 1, element, size + sizeof(T)),
     43                RightOOBWriteMessage(0));
     44   // whole interval is to the right
     45   EXPECT_DEATH(MEMSET(array + length + 1, 0, 10),
     46                RightOOBWriteMessage(sizeof(T)));
     47 
     48   // try to memset bytes to the left of array
     49   EXPECT_DEATH(MEMSET((char*)array - 1, element, size),
     50                LeftOOBWriteMessage(1));
     51   EXPECT_DEATH(MEMSET((char*)array - 5, 0, 6),
     52                LeftOOBWriteMessage(5));
     53   if (length >= 100) {
     54     // Large OOB, we find it only if the redzone is large enough.
     55     EXPECT_DEATH(memset(array - 5, element, size + 5 * sizeof(T)),
     56                  LeftOOBWriteMessage(5 * sizeof(T)));
     57   }
     58   // whole interval is to the left
     59   EXPECT_DEATH(MEMSET(array - 2, 0, sizeof(T)),
     60                LeftOOBWriteMessage(2 * sizeof(T)));
     61 
     62   // try to memset bytes both to the left & to the right
     63   EXPECT_DEATH(MEMSET((char*)array - 2, element, size + 4),
     64                LeftOOBWriteMessage(2));
     65 
     66   free(array);
     67 }
     68 
     69 TEST(AddressSanitizer, MemSetOOBTest) {
     70   MemSetOOBTestTemplate<char>(100);
     71   MemSetOOBTestTemplate<int>(5);
     72   MemSetOOBTestTemplate<double>(256);
     73   // We can test arrays of structres/classes here, but what for?
     74 }
     75 
     76 // Try to allocate two arrays of 'size' bytes that are near each other.
     77 // Strictly speaking we are not guaranteed to find such two pointers,
     78 // but given the structure of asan's allocator we will.
     79 static bool AllocateTwoAdjacentArrays(char **x1, char **x2, size_t size) {
     80   std::vector<uintptr_t> v;
     81   bool res = false;
     82   for (size_t i = 0; i < 1000U && !res; i++) {
     83     v.push_back(reinterpret_cast<uintptr_t>(new char[size]));
     84     if (i == 0) continue;
     85     sort(v.begin(), v.end());
     86     for (size_t j = 1; j < v.size(); j++) {
     87       assert(v[j] > v[j-1]);
     88       if ((size_t)(v[j] - v[j-1]) < size * 2) {
     89         *x2 = reinterpret_cast<char*>(v[j]);
     90         *x1 = reinterpret_cast<char*>(v[j-1]);
     91         res = true;
     92         break;
     93       }
     94     }
     95   }
     96 
     97   for (size_t i = 0; i < v.size(); i++) {
     98     char *p = reinterpret_cast<char *>(v[i]);
     99     if (res && p == *x1) continue;
    100     if (res && p == *x2) continue;
    101     delete [] p;
    102   }
    103   return res;
    104 }
    105 
    106 TEST(AddressSanitizer, LargeOOBInMemset) {
    107   for (size_t size = 200; size < 100000; size += size / 2) {
    108     char *x1, *x2;
    109     if (!Ident(AllocateTwoAdjacentArrays)(&x1, &x2, size))
    110       continue;
    111     // fprintf(stderr, "  large oob memset: %p %p %zd\n", x1, x2, size);
    112     // Do a memset on x1 with huge out-of-bound access that will end up in x2.
    113     EXPECT_DEATH(Ident(memset)(x1, 0, size * 2),
    114                  "is located 0 bytes to the right");
    115     delete [] x1;
    116     delete [] x2;
    117     return;
    118   }
    119   assert(0 && "Did not find two adjacent malloc-ed pointers");
    120 }
    121 
    122 // Same test for memcpy and memmove functions
    123 template <typename T, class M>
    124 void MemTransferOOBTestTemplate(size_t length) {
    125   if (length == 0) return;
    126   size_t size = Ident(sizeof(T) * length);
    127   T *src = Ident((T*)malloc(size));
    128   T *dest = Ident((T*)malloc(size));
    129   int zero = Ident(0);
    130 
    131   // valid transfer of bytes between arrays
    132   M::transfer(dest, src, size);
    133   M::transfer(dest + 1, src, size - sizeof(T));
    134   M::transfer(dest, src + length - 1, sizeof(T));
    135   M::transfer(dest, src, 1);
    136 
    137   // transfer zero bytes
    138   M::transfer(dest - 1, src, 0);
    139   M::transfer(dest + length, src, zero);
    140   M::transfer(dest, src - 1, zero);
    141   M::transfer(dest, src, zero);
    142 
    143   // try to change mem to the right of dest
    144   EXPECT_DEATH(M::transfer(dest + 1, src, size),
    145                RightOOBWriteMessage(0));
    146   EXPECT_DEATH(M::transfer((char*)(dest + length) - 1, src, 5),
    147                RightOOBWriteMessage(0));
    148 
    149   // try to change mem to the left of dest
    150   EXPECT_DEATH(M::transfer(dest - 2, src, size),
    151                LeftOOBWriteMessage(2 * sizeof(T)));
    152   EXPECT_DEATH(M::transfer((char*)dest - 3, src, 4),
    153                LeftOOBWriteMessage(3));
    154 
    155   // try to access mem to the right of src
    156   EXPECT_DEATH(M::transfer(dest, src + 2, size),
    157                RightOOBReadMessage(0));
    158   EXPECT_DEATH(M::transfer(dest, (char*)(src + length) - 3, 6),
    159                RightOOBReadMessage(0));
    160 
    161   // try to access mem to the left of src
    162   EXPECT_DEATH(M::transfer(dest, src - 1, size),
    163                LeftOOBReadMessage(sizeof(T)));
    164   EXPECT_DEATH(M::transfer(dest, (char*)src - 6, 7),
    165                LeftOOBReadMessage(6));
    166 
    167   // Generally we don't need to test cases where both accessing src and writing
    168   // to dest address to poisoned memory.
    169 
    170   T *big_src = Ident((T*)malloc(size * 2));
    171   T *big_dest = Ident((T*)malloc(size * 2));
    172   // try to change mem to both sides of dest
    173   EXPECT_DEATH(M::transfer(dest - 1, big_src, size * 2),
    174                LeftOOBWriteMessage(sizeof(T)));
    175   // try to access mem to both sides of src
    176   EXPECT_DEATH(M::transfer(big_dest, src - 2, size * 2),
    177                LeftOOBReadMessage(2 * sizeof(T)));
    178 
    179   free(src);
    180   free(dest);
    181   free(big_src);
    182   free(big_dest);
    183 }
    184 
    185 class MemCpyWrapper {
    186  public:
    187   static void* transfer(void *to, const void *from, size_t size) {
    188     return Ident(memcpy)(to, from, size);
    189   }
    190 };
    191 
    192 TEST(AddressSanitizer, MemCpyOOBTest) {
    193   MemTransferOOBTestTemplate<char, MemCpyWrapper>(100);
    194   MemTransferOOBTestTemplate<int, MemCpyWrapper>(1024);
    195 }
    196 
    197 class MemMoveWrapper {
    198  public:
    199   static void* transfer(void *to, const void *from, size_t size) {
    200     return Ident(memmove)(to, from, size);
    201   }
    202 };
    203 
    204 TEST(AddressSanitizer, MemMoveOOBTest) {
    205   MemTransferOOBTestTemplate<char, MemMoveWrapper>(100);
    206   MemTransferOOBTestTemplate<int, MemMoveWrapper>(1024);
    207 }
    208 
    209 
    210 TEST(AddressSanitizer, MemCmpOOBTest) {
    211   size_t size = Ident(100);
    212   char *s1 = MallocAndMemsetString(size);
    213   char *s2 = MallocAndMemsetString(size);
    214   // Normal memcmp calls.
    215   Ident(memcmp(s1, s2, size));
    216   Ident(memcmp(s1 + size - 1, s2 + size - 1, 1));
    217   Ident(memcmp(s1 - 1, s2 - 1, 0));
    218   // One of arguments points to not allocated memory.
    219   EXPECT_DEATH(Ident(memcmp)(s1 - 1, s2, 1), LeftOOBReadMessage(1));
    220   EXPECT_DEATH(Ident(memcmp)(s1, s2 - 1, 1), LeftOOBReadMessage(1));
    221   EXPECT_DEATH(Ident(memcmp)(s1 + size, s2, 1), RightOOBReadMessage(0));
    222   EXPECT_DEATH(Ident(memcmp)(s1, s2 + size, 1), RightOOBReadMessage(0));
    223   // Hit unallocated memory and die.
    224   EXPECT_DEATH(Ident(memcmp)(s1 + 1, s2 + 1, size), RightOOBReadMessage(0));
    225   EXPECT_DEATH(Ident(memcmp)(s1 + size - 1, s2, 2), RightOOBReadMessage(0));
    226   // Zero bytes are not terminators and don't prevent from OOB.
    227   s1[size - 1] = '\0';
    228   s2[size - 1] = '\0';
    229   EXPECT_DEATH(Ident(memcmp)(s1, s2, size + 1), RightOOBReadMessage(0));
    230 
    231   // Even if the buffers differ in the first byte, we still assume that
    232   // memcmp may access the whole buffer and thus reporting the overflow here:
    233   s1[0] = 1;
    234   s2[0] = 123;
    235   EXPECT_DEATH(Ident(memcmp)(s1, s2, size + 1), RightOOBReadMessage(0));
    236 
    237   free(s1);
    238   free(s2);
    239 }
    240 
    241 
    242 
    243