brintos

brintos / llvm-project-archived public Read only

0
0
Text · 4.4 KiB · ce4c90c Raw
141 lines · cpp
1//===-- asan_oob_test.cpp -------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file is a part of AddressSanitizer, an address sanity checker.10//11//===----------------------------------------------------------------------===//12#include "asan_test_utils.h"13 14#ifdef __sparc__15// Tests using unaligned accesses cannot work on strict-alignment targets.16#define SKIP_ON_STRICT_ALIGNMENT(x) DISABLED_##x17#else18#define SKIP_ON_STRICT_ALIGNMENT(x) x19#endif20 21NOINLINE void asan_write_sized_aligned(uint8_t *p, size_t size) {22  EXPECT_EQ(0U, ((uintptr_t)p % size));23  if      (size == 1) asan_write((uint8_t*)p);24  else if (size == 2) asan_write((uint16_t*)p);25  else if (size == 4) asan_write((uint32_t*)p);26  else if (size == 8) asan_write((uint64_t*)p);27}28 29template<typename T>30NOINLINE void oob_test(int size, int off) {31  char *p = (char*)malloc_aaa(size);32  // fprintf(stderr, "writing %d byte(s) into [%p,%p) with offset %d\n",33  //        sizeof(T), p, p + size, off);34  asan_write((T*)(p + off));35  free_aaa(p);36}37 38static std::string GetLeftOOBMessage(int off) {39  char str[100];40  sprintf(str, "is located.*%d byte.*before", off);41  return str;42}43 44static std::string GetRightOOBMessage(int off) {45  char str[100];46#if !defined(_WIN32)47  // FIXME: Fix PR42868 and remove SEGV match.48  sprintf(str, "is located.*%d byte.*after|SEGV", off);49#else50  // `|` doesn't work in googletest's regexes on Windows,51  // see googletest/docs/advanced.md#regular-expression-syntax52  // But it's not needed on Windows anyways.53  sprintf(str, "is located.*%d byte.*after", off);54#endif55  return str;56}57 58template<typename T>59void OOBTest() {60  for (int size = sizeof(T); size < 20; size += 5) {61    for (int i = -5; i < 0; i++)62      EXPECT_DEATH(oob_test<T>(size, i), GetLeftOOBMessage(-i));63 64    for (int i = 0; i < (int)(size - sizeof(T) + 1); i++)65      oob_test<T>(size, i);66 67    for (int i = size - sizeof(T) + 1; i <= (int)(size + 2 * sizeof(T)); i++) {68      // we don't catch unaligned partially OOB accesses.69      if (i % sizeof(T)) continue;70      int off = i >= size ? (i - size) : 0;71      EXPECT_DEATH(oob_test<T>(size, i), GetRightOOBMessage(off));72    }73  }74 75  EXPECT_DEATH(oob_test<T>(kLargeMalloc, -1), GetLeftOOBMessage(1));76  EXPECT_DEATH(oob_test<T>(kLargeMalloc, kLargeMalloc), GetRightOOBMessage(0));77}78 79// TODO(glider): the following tests are EXTREMELY slow on Darwin:80//   AddressSanitizer.OOB_char (125503 ms)81//   AddressSanitizer.OOB_int (126890 ms)82//   AddressSanitizer.OOBRightTest (315605 ms)83//   AddressSanitizer.SimpleStackTest (366559 ms)84 85TEST(AddressSanitizer, OOB_char) {86  OOBTest<U1>();87}88 89TEST(AddressSanitizer, SKIP_ON_STRICT_ALIGNMENT(OOB_int)) {90  OOBTest<U4>();91}92 93TEST(AddressSanitizer, OOBRightTest) {94  size_t max_access_size = SANITIZER_WORDSIZE == 64 ? 8 : 4;95  for (size_t access_size = 1; access_size <= max_access_size;96       access_size *= 2) {97    for (size_t alloc_size = 1; alloc_size <= 8; alloc_size++) {98      for (size_t offset = 0; offset <= 8; offset += access_size) {99        void *p = malloc(alloc_size);100        // allocated: [p, p + alloc_size)101        // accessed:  [p + offset, p + offset + access_size)102        uint8_t *addr = (uint8_t*)p + offset;103        if (offset + access_size <= alloc_size) {104          asan_write_sized_aligned(addr, access_size);105        } else {106          int outside_bytes = offset > alloc_size ? (offset - alloc_size) : 0;107          EXPECT_DEATH(asan_write_sized_aligned(addr, access_size),108                       GetRightOOBMessage(outside_bytes));109        }110        free(p);111      }112    }113  }114}115 116TEST(AddressSanitizer, LargeOOBRightTest) {117  size_t large_power_of_two = 1 << 19;118  for (size_t i = 16; i <= 256; i *= 2) {119    size_t size = large_power_of_two - i;120    char *p = Ident(new char[size]);121    EXPECT_DEATH(p[size] = 0, GetRightOOBMessage(0));122    delete [] p;123  }124}125 126TEST(AddressSanitizer, DISABLED_DemoOOBLeftLow) {127  oob_test<U1>(10, -1);128}129 130TEST(AddressSanitizer, DISABLED_DemoOOBLeftHigh) {131  oob_test<U1>(kLargeMalloc, -1);132}133 134TEST(AddressSanitizer, DISABLED_DemoOOBRightLow) {135  oob_test<U1>(10, 10);136}137 138TEST(AddressSanitizer, DISABLED_DemoOOBRightHigh) {139  oob_test<U1>(kLargeMalloc, kLargeMalloc);140}141