138db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany//===-- asan_oob_test.cc --------------------------------------------------===// 238db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany// 338db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany// The LLVM Compiler Infrastructure 438db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany// 538db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany// This file is distributed under the University of Illinois Open Source 638db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany// License. See LICENSE.TXT for details. 738db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany// 838db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany//===----------------------------------------------------------------------===// 938db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany// 1038db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany// This file is a part of AddressSanitizer, an address sanity checker. 1138db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany// 1238db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany//===----------------------------------------------------------------------===// 1338db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany#include "asan_test_utils.h" 1438db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany 1538db30686c5962f8b5c877e29c6669d72198d42bKostya SerebryanyNOINLINE void asan_write_sized_aligned(uint8_t *p, size_t size) { 1638db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany EXPECT_EQ(0U, ((uintptr_t)p % size)); 1738db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany if (size == 1) asan_write((uint8_t*)p); 1838db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany else if (size == 2) asan_write((uint16_t*)p); 1938db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany else if (size == 4) asan_write((uint32_t*)p); 2038db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany else if (size == 8) asan_write((uint64_t*)p); 2138db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany} 2238db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany 2338db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryanytemplate<typename T> 2438db30686c5962f8b5c877e29c6669d72198d42bKostya SerebryanyNOINLINE void oob_test(int size, int off) { 2538db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany char *p = (char*)malloc_aaa(size); 2638db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany // fprintf(stderr, "writing %d byte(s) into [%p,%p) with offset %d\n", 2738db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany // sizeof(T), p, p + size, off); 2838db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany asan_write((T*)(p + off)); 2938db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany free_aaa(p); 3038db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany} 3138db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany 3238db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryanytemplate<typename T> 3338db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryanyvoid OOBTest() { 3438db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany char expected_str[100]; 3538db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany for (int size = sizeof(T); size < 20; size += 5) { 3638db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany for (int i = -5; i < 0; i++) { 3738db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany const char *str = 3838db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany "is located.*%d byte.*to the left"; 3938db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany sprintf(expected_str, str, abs(i)); 4038db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany EXPECT_DEATH(oob_test<T>(size, i), expected_str); 4138db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany } 4238db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany 4338db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany for (int i = 0; i < (int)(size - sizeof(T) + 1); i++) 4438db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany oob_test<T>(size, i); 4538db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany 4638db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany for (int i = size - sizeof(T) + 1; i <= (int)(size + 2 * sizeof(T)); i++) { 4738db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany const char *str = 4838db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany "is located.*%d byte.*to the right"; 4938db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany int off = i >= size ? (i - size) : 0; 5038db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany // we don't catch unaligned partially OOB accesses. 5138db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany if (i % sizeof(T)) continue; 5238db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany sprintf(expected_str, str, off); 5338db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany EXPECT_DEATH(oob_test<T>(size, i), expected_str); 5438db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany } 5538db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany } 5638db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany 5738db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany EXPECT_DEATH(oob_test<T>(kLargeMalloc, -1), 5838db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany "is located.*1 byte.*to the left"); 5938db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany EXPECT_DEATH(oob_test<T>(kLargeMalloc, kLargeMalloc), 6038db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany "is located.*0 byte.*to the right"); 6138db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany} 6238db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany 6338db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany// TODO(glider): the following tests are EXTREMELY slow on Darwin: 6438db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany// AddressSanitizer.OOB_char (125503 ms) 6538db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany// AddressSanitizer.OOB_int (126890 ms) 6638db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany// AddressSanitizer.OOBRightTest (315605 ms) 6738db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany// AddressSanitizer.SimpleStackTest (366559 ms) 6838db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany 6938db30686c5962f8b5c877e29c6669d72198d42bKostya SerebryanyTEST(AddressSanitizer, OOB_char) { 7038db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany OOBTest<U1>(); 7138db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany} 7238db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany 7338db30686c5962f8b5c877e29c6669d72198d42bKostya SerebryanyTEST(AddressSanitizer, OOB_int) { 7438db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany OOBTest<U4>(); 7538db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany} 7638db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany 7738db30686c5962f8b5c877e29c6669d72198d42bKostya SerebryanyTEST(AddressSanitizer, OOBRightTest) { 782d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines size_t max_access_size = SANITIZER_WORDSIZE == 64 ? 8 : 4; 792d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines for (size_t access_size = 1; access_size <= max_access_size; 802d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines access_size *= 2) { 8138db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany for (size_t alloc_size = 1; alloc_size <= 8; alloc_size++) { 8238db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany for (size_t offset = 0; offset <= 8; offset += access_size) { 8338db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany void *p = malloc(alloc_size); 8438db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany // allocated: [p, p + alloc_size) 8538db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany // accessed: [p + offset, p + offset + access_size) 8638db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany uint8_t *addr = (uint8_t*)p + offset; 8738db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany if (offset + access_size <= alloc_size) { 8838db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany asan_write_sized_aligned(addr, access_size); 8938db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany } else { 9038db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany int outside_bytes = offset > alloc_size ? (offset - alloc_size) : 0; 9138db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany const char *str = 9238db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany "is located.%d *byte.*to the right"; 9338db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany char expected_str[100]; 9438db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany sprintf(expected_str, str, outside_bytes); 9538db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany EXPECT_DEATH(asan_write_sized_aligned(addr, access_size), 9638db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany expected_str); 9738db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany } 9838db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany free(p); 9938db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany } 10038db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany } 10138db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany } 10238db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany} 10338db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany 10438db30686c5962f8b5c877e29c6669d72198d42bKostya SerebryanyTEST(AddressSanitizer, LargeOOBRightTest) { 10538db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany size_t large_power_of_two = 1 << 19; 10638db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany for (size_t i = 16; i <= 256; i *= 2) { 10738db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany size_t size = large_power_of_two - i; 10838db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany char *p = Ident(new char[size]); 10938db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany EXPECT_DEATH(p[size] = 0, "is located 0 bytes to the right"); 11038db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany delete [] p; 11138db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany } 11238db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany} 11338db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany 11438db30686c5962f8b5c877e29c6669d72198d42bKostya SerebryanyTEST(AddressSanitizer, DISABLED_DemoOOBLeftLow) { 11538db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany oob_test<U1>(10, -1); 11638db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany} 11738db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany 11838db30686c5962f8b5c877e29c6669d72198d42bKostya SerebryanyTEST(AddressSanitizer, DISABLED_DemoOOBLeftHigh) { 11938db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany oob_test<U1>(kLargeMalloc, -1); 12038db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany} 12138db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany 12238db30686c5962f8b5c877e29c6669d72198d42bKostya SerebryanyTEST(AddressSanitizer, DISABLED_DemoOOBRightLow) { 12338db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany oob_test<U1>(10, 10); 12438db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany} 12538db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany 12638db30686c5962f8b5c877e29c6669d72198d42bKostya SerebryanyTEST(AddressSanitizer, DISABLED_DemoOOBRightHigh) { 12738db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany oob_test<U1>(kLargeMalloc, kLargeMalloc); 12838db30686c5962f8b5c877e29c6669d72198d42bKostya Serebryany} 129