asan_test.C: Add -std=c++11 and -DSANITIZER_USE_DEJAGNU_GTEST=1 to dg-options...

* g++.dg/asan/asan_test.C: Add -std=c++11 and
	-DSANITIZER_USE_DEJAGNU_GTEST=1 to dg-options, remove
	-DASAN_USE_DEJAGNU_GTEST=1.
	* g++.dg/asan/asan_mem_test.cc: Updated from upstream
	r209283.
	* g++.dg/asan/asan_oob_test.cc: Likewise.
	* g++.dg/asan/sanitizer_test_utils.h: Likewise.
	* g++.dg/asan/asan_str_test.cc: Likewise.
	* g++.dg/asan/asan_test_utils.h: Likewise.
	* g++.dg/asan/sanitizer_test_config.h: Likewise.
	* g++.dg/asan/asan_test.cc: Likewise.  Allow size 12
	for long double.
	* g++.dg/asan/sanitizer_pthread_wrappers.h: New file.
	Imported from upstream r209283.
	* g++.dg/asan/asan_test_config.h: Likewise.

From-SVN: r211090
This commit is contained in:
Jakub Jelinek 2014-05-30 20:36:24 +02:00 committed by Jakub Jelinek
parent cb10592208
commit 8465be9f1d
11 changed files with 470 additions and 191 deletions

View file

@ -1,3 +1,21 @@
2014-05-30 Jakub Jelinek <jakub@redhat.com>
* g++.dg/asan/asan_test.C: Add -std=c++11 and
-DSANITIZER_USE_DEJAGNU_GTEST=1 to dg-options, remove
-DASAN_USE_DEJAGNU_GTEST=1.
* g++.dg/asan/asan_mem_test.cc: Updated from upstream
r209283.
* g++.dg/asan/asan_oob_test.cc: Likewise.
* g++.dg/asan/sanitizer_test_utils.h: Likewise.
* g++.dg/asan/asan_str_test.cc: Likewise.
* g++.dg/asan/asan_test_utils.h: Likewise.
* g++.dg/asan/sanitizer_test_config.h: Likewise.
* g++.dg/asan/asan_test.cc: Likewise. Allow size 12
for long double.
* g++.dg/asan/sanitizer_pthread_wrappers.h: New file.
Imported from upstream r209283.
* g++.dg/asan/asan_test_config.h: Likewise.
2014-05-30 Ian Lance Taylor <iant@google.com>
* gcc.target/i386/pause-2.c: New test.

View file

@ -74,17 +74,17 @@ TEST(AddressSanitizer, MemSetOOBTest) {
// Strictly speaking we are not guaranteed to find such two pointers,
// but given the structure of asan's allocator we will.
static bool AllocateTwoAdjacentArrays(char **x1, char **x2, size_t size) {
vector<char *> v;
vector<uintptr_t> v;
bool res = false;
for (size_t i = 0; i < 1000U && !res; i++) {
v.push_back(new char[size]);
v.push_back(reinterpret_cast<uintptr_t>(new char[size]));
if (i == 0) continue;
sort(v.begin(), v.end());
for (size_t j = 1; j < v.size(); j++) {
assert(v[j] > v[j-1]);
if ((size_t)(v[j] - v[j-1]) < size * 2) {
*x2 = v[j];
*x1 = v[j-1];
*x2 = reinterpret_cast<char*>(v[j]);
*x1 = reinterpret_cast<char*>(v[j-1]);
res = true;
break;
}
@ -92,9 +92,10 @@ static bool AllocateTwoAdjacentArrays(char **x1, char **x2, size_t size) {
}
for (size_t i = 0; i < v.size(); i++) {
if (res && v[i] == *x1) continue;
if (res && v[i] == *x2) continue;
delete [] v[i];
char *p = reinterpret_cast<char *>(v[i]);
if (res && p == *x1) continue;
if (res && p == *x2) continue;
delete [] p;
}
return res;
}
@ -223,6 +224,13 @@ TEST(AddressSanitizer, MemCmpOOBTest) {
s1[size - 1] = '\0';
s2[size - 1] = '\0';
EXPECT_DEATH(Ident(memcmp)(s1, s2, size + 1), RightOOBReadMessage(0));
// Even if the buffers differ in the first byte, we still assume that
// memcmp may access the whole buffer and thus reporting the overflow here:
s1[0] = 1;
s2[0] = 123;
EXPECT_DEATH(Ident(memcmp)(s1, s2, size + 1), RightOOBReadMessage(0));
free(s1);
free(s2);
}

View file

@ -97,7 +97,6 @@ TEST(AddressSanitizer, OOBRightTest) {
}
}
#if ASAN_ALLOCATOR_VERSION == 2 // Broken with the asan_allocator1
TEST(AddressSanitizer, LargeOOBRightTest) {
size_t large_power_of_two = 1 << 19;
for (size_t i = 16; i <= 256; i *= 2) {
@ -107,7 +106,6 @@ TEST(AddressSanitizer, LargeOOBRightTest) {
delete [] p;
}
}
#endif // ASAN_ALLOCATOR_VERSION == 2
TEST(AddressSanitizer, DISABLED_DemoOOBLeftLow) {
oob_test<U1>(10, -1);

View file

@ -10,6 +10,10 @@
//===----------------------------------------------------------------------===//
#include "asan_test_utils.h"
#if defined(__APPLE__)
#include <AvailabilityMacros.h> // For MAC_OS_X_VERSION_*
#endif
// Used for string functions tests
static char global_string[] = "global";
static size_t global_string_length = 6;
@ -59,7 +63,19 @@ TEST(AddressSanitizer, StrLenOOBTest) {
free(heap_string);
}
#ifndef __APPLE__
TEST(AddressSanitizer, WcsLenTest) {
EXPECT_EQ(0U, wcslen(Ident(L"")));
size_t hello_len = 13;
size_t hello_size = (hello_len + 1) * sizeof(wchar_t);
EXPECT_EQ(hello_len, wcslen(Ident(L"Hello, World!")));
wchar_t *heap_string = Ident((wchar_t*)malloc(hello_size));
memcpy(heap_string, L"Hello, World!", hello_size);
EXPECT_EQ(hello_len, Ident(wcslen(heap_string)));
EXPECT_DEATH(Ident(wcslen(heap_string + 14)), RightOOBReadMessage(0));
free(heap_string);
}
#if SANITIZER_TEST_HAS_STRNLEN
TEST(AddressSanitizer, StrNLenOOBTest) {
size_t size = Ident(123);
char *str = MallocAndMemsetString(size);
@ -77,7 +93,7 @@ TEST(AddressSanitizer, StrNLenOOBTest) {
EXPECT_DEATH(Ident(strnlen(str, size + 1)), RightOOBReadMessage(0));
free(str);
}
#endif
#endif // SANITIZER_TEST_HAS_STRNLEN
TEST(AddressSanitizer, StrDupOOBTest) {
size_t size = Ident(42);
@ -168,7 +184,7 @@ TEST(AddressSanitizer, StrNCpyOOBTest) {
typedef char*(*PointerToStrChr1)(const char*, int);
typedef char*(*PointerToStrChr2)(char*, int);
USED static void RunStrChrTest(PointerToStrChr1 StrChr) {
UNUSED static void RunStrChrTest(PointerToStrChr1 StrChr) {
size_t size = Ident(100);
char *str = MallocAndMemsetString(size);
str[10] = 'q';
@ -184,7 +200,7 @@ USED static void RunStrChrTest(PointerToStrChr1 StrChr) {
EXPECT_DEATH(Ident(StrChr(str, 'a')), RightOOBReadMessage(0));
free(str);
}
USED static void RunStrChrTest(PointerToStrChr2 StrChr) {
UNUSED static void RunStrChrTest(PointerToStrChr2 StrChr) {
size_t size = Ident(100);
char *str = MallocAndMemsetString(size);
str[10] = 'q';
@ -203,7 +219,9 @@ USED static void RunStrChrTest(PointerToStrChr2 StrChr) {
TEST(AddressSanitizer, StrChrAndIndexOOBTest) {
RunStrChrTest(&strchr);
#if !defined(_WIN32) // no index() on Windows.
RunStrChrTest(&index);
#endif
}
TEST(AddressSanitizer, StrCmpAndFriendsLogicTest) {
@ -226,6 +244,7 @@ TEST(AddressSanitizer, StrCmpAndFriendsLogicTest) {
EXPECT_LT(0, strncmp("baa", "aaa", 1));
EXPECT_LT(0, strncmp("zyx", "", 2));
#if !defined(_WIN32) // no str[n]casecmp on Windows.
// strcasecmp
EXPECT_EQ(0, strcasecmp("", ""));
EXPECT_EQ(0, strcasecmp("zzz", "zzz"));
@ -245,6 +264,7 @@ TEST(AddressSanitizer, StrCmpAndFriendsLogicTest) {
EXPECT_LT(0, strncasecmp("xyz", "xyy", 10));
EXPECT_LT(0, strncasecmp("Baa", "aaa", 1));
EXPECT_LT(0, strncasecmp("zyx", "", 2));
#endif
// memcmp
EXPECT_EQ(0, memcmp("a", "b", 0));
@ -287,9 +307,11 @@ TEST(AddressSanitizer, StrCmpOOBTest) {
RunStrCmpTest(&strcmp);
}
#if !defined(_WIN32) // no str[n]casecmp on Windows.
TEST(AddressSanitizer, StrCaseCmpOOBTest) {
RunStrCmpTest(&strcasecmp);
}
#endif
typedef int(*PointerToStrNCmp)(const char*, const char*, size_t);
void RunStrNCmpTest(PointerToStrNCmp StrNCmp) {
@ -322,9 +344,12 @@ TEST(AddressSanitizer, StrNCmpOOBTest) {
RunStrNCmpTest(&strncmp);
}
#if !defined(_WIN32) // no str[n]casecmp on Windows.
TEST(AddressSanitizer, StrNCaseCmpOOBTest) {
RunStrNCmpTest(&strncasecmp);
}
#endif
TEST(AddressSanitizer, StrCatOOBTest) {
// strcat() reads strlen(to) bytes from |to| before concatenating.
size_t to_size = Ident(100);
@ -506,11 +531,13 @@ void RunAtoiOOBTest(PointerToCallAtoi Atoi) {
free(array);
}
#if !defined(_WIN32) // FIXME: Fix and enable on Windows.
TEST(AddressSanitizer, AtoiAndFriendsOOBTest) {
RunAtoiOOBTest(&CallAtoi);
RunAtoiOOBTest(&CallAtol);
RunAtoiOOBTest(&CallAtoll);
}
#endif
void CallStrtol(const char *nptr, char **endptr, int base) {
Ident(strtol(nptr, endptr, base));
@ -560,11 +587,13 @@ void RunStrtolOOBTest(PointerToCallStrtol Strtol) {
free(array);
}
#if !defined(_WIN32) // FIXME: Fix and enable on Windows.
TEST(AddressSanitizer, StrtollOOBTest) {
RunStrtolOOBTest(&CallStrtoll);
}
TEST(AddressSanitizer, StrtolOOBTest) {
RunStrtolOOBTest(&CallStrtol);
}
#endif

View file

@ -2,7 +2,7 @@
// { dg-skip-if "" { *-*-* } { "*" } { "-O2" } }
// { dg-skip-if "" { *-*-* } { "-flto" } { "" } }
// { dg-additional-sources "asan_globals_test-wrapper.cc" }
// { dg-options "-fsanitize=address -fno-builtin -Wall -Wno-format -Werror -g -DASAN_UAR=0 -DASAN_HAS_EXCEPTIONS=1 -DASAN_HAS_BLACKLIST=0 -DASAN_USE_DEJAGNU_GTEST=1 -lasan -lpthread -ldl" }
// { dg-options "-std=c++11 -fsanitize=address -fno-builtin -Wall -Wno-format -Werror -g -DASAN_UAR=0 -DASAN_HAS_EXCEPTIONS=1 -DASAN_HAS_BLACKLIST=0 -DSANITIZER_USE_DEJAGNU_GTEST=1 -lasan -lpthread -ldl" }
// { dg-additional-options "-DASAN_NEEDS_SEGV=1" { target { ! arm*-*-* } } }
// { dg-additional-options "-DASAN_LOW_MEMORY=1 -DASAN_NEEDS_SEGV=0" { target arm*-*-* } }
// { dg-additional-options "-DASAN_AVOID_EXPENSIVE_TESTS=1" { target { ! run_expensive_tests } } }

View file

@ -23,27 +23,10 @@ NOINLINE void *malloc_bbb(size_t size) {
NOINLINE void *malloc_aaa(size_t size) {
void *res = malloc_bbb(size); break_optimization(0); return res;}
#ifndef __APPLE__
NOINLINE void *memalign_fff(size_t alignment, size_t size) {
void *res = memalign/**/(alignment, size); break_optimization(0); return res;}
NOINLINE void *memalign_eee(size_t alignment, size_t size) {
void *res = memalign_fff(alignment, size); break_optimization(0); return res;}
NOINLINE void *memalign_ddd(size_t alignment, size_t size) {
void *res = memalign_eee(alignment, size); break_optimization(0); return res;}
NOINLINE void *memalign_ccc(size_t alignment, size_t size) {
void *res = memalign_ddd(alignment, size); break_optimization(0); return res;}
NOINLINE void *memalign_bbb(size_t alignment, size_t size) {
void *res = memalign_ccc(alignment, size); break_optimization(0); return res;}
NOINLINE void *memalign_aaa(size_t alignment, size_t size) {
void *res = memalign_bbb(alignment, size); break_optimization(0); return res;}
#endif // __APPLE__
NOINLINE void free_ccc(void *p) { free(p); break_optimization(0);}
NOINLINE void free_bbb(void *p) { free_ccc(p); break_optimization(0);}
NOINLINE void free_aaa(void *p) { free_bbb(p); break_optimization(0);}
template<typename T>
NOINLINE void uaf_test(int size, int off) {
char *p = (char *)malloc_aaa(size);
@ -88,19 +71,19 @@ TEST(AddressSanitizer, VariousMallocsTest) {
*c = 0;
delete c;
#if !defined(__APPLE__) && !defined(ANDROID) && !defined(__ANDROID__)
#if SANITIZER_TEST_HAS_POSIX_MEMALIGN
int *pm;
int pm_res = posix_memalign((void**)&pm, kPageSize, kPageSize);
EXPECT_EQ(0, pm_res);
free(pm);
#endif
#endif // SANITIZER_TEST_HAS_POSIX_MEMALIGN
#if !defined(__APPLE__)
#if SANITIZER_TEST_HAS_MEMALIGN
int *ma = (int*)memalign(kPageSize, kPageSize);
EXPECT_EQ(0U, (uintptr_t)ma % kPageSize);
ma[123] = 0;
free(ma);
#endif // __APPLE__
#endif // SANITIZER_TEST_HAS_MEMALIGN
}
TEST(AddressSanitizer, CallocTest) {
@ -109,13 +92,37 @@ TEST(AddressSanitizer, CallocTest) {
free(a);
}
TEST(AddressSanitizer, CallocReturnsZeroMem) {
size_t sizes[] = {16, 1000, 10000, 100000, 2100000};
for (size_t s = 0; s < sizeof(sizes)/sizeof(sizes[0]); s++) {
size_t size = sizes[s];
for (size_t iter = 0; iter < 5; iter++) {
char *x = Ident((char*)calloc(1, size));
EXPECT_EQ(x[0], 0);
EXPECT_EQ(x[size - 1], 0);
EXPECT_EQ(x[size / 2], 0);
EXPECT_EQ(x[size / 3], 0);
EXPECT_EQ(x[size / 4], 0);
memset(x, 0x42, size);
free(Ident(x));
#if !defined(_WIN32)
// FIXME: OOM on Windows. We should just make this a lit test
// with quarantine size set to 1.
free(Ident(malloc(Ident(1 << 27)))); // Try to drain the quarantine.
#endif
}
}
}
#if !defined(_WIN32) // No valloc on Windows.
TEST(AddressSanitizer, VallocTest) {
void *a = valloc(100);
EXPECT_EQ(0U, (uintptr_t)a % kPageSize);
free(a);
}
#endif
#ifndef __APPLE__
#if SANITIZER_TEST_HAS_PVALLOC
TEST(AddressSanitizer, PvallocTest) {
char *a = (char*)pvalloc(kPageSize + 100);
EXPECT_EQ(0U, (uintptr_t)a % kPageSize);
@ -127,8 +134,10 @@ TEST(AddressSanitizer, PvallocTest) {
a[101] = 1; // we should not report an error here.
free(a);
}
#endif // __APPLE__
#endif // SANITIZER_TEST_HAS_PVALLOC
#if !defined(_WIN32)
// FIXME: Use an equivalent of pthread_setspecific on Windows.
void *TSDWorker(void *test_key) {
if (test_key) {
pthread_setspecific(*(pthread_key_t*)test_key, (void*)0xfeedface);
@ -158,6 +167,7 @@ TEST(AddressSanitizer, DISABLED_TSDTest) {
PTHREAD_JOIN(th, NULL);
pthread_key_delete(test_key);
}
#endif
TEST(AddressSanitizer, UAF_char) {
const char *uaf_string = "AddressSanitizer:.*heap-use-after-free";
@ -168,6 +178,36 @@ TEST(AddressSanitizer, UAF_char) {
EXPECT_DEATH(uaf_test<U1>(kLargeMalloc, kLargeMalloc / 2), uaf_string);
}
TEST(AddressSanitizer, UAF_long_double) {
if (sizeof(long double) == sizeof(double)) return;
long double *p = Ident(new long double[10]);
EXPECT_DEATH(Ident(p)[12] = 0, "WRITE of size 1[026]");
EXPECT_DEATH(Ident(p)[0] = Ident(p)[12], "READ of size 1[026]");
delete [] Ident(p);
}
#if !defined(_WIN32)
struct Packed5 {
int x;
char c;
} __attribute__((packed));
#else
# pragma pack(push, 1)
struct Packed5 {
int x;
char c;
};
# pragma pack(pop)
#endif
TEST(AddressSanitizer, UAF_Packed5) {
static_assert(sizeof(Packed5) == 5, "Please check the keywords used");
Packed5 *p = Ident(new Packed5[2]);
EXPECT_DEATH(p[0] = p[3], "READ of size 5");
EXPECT_DEATH(p[3] = p[0], "WRITE of size 5");
delete [] Ident(p);
}
#if ASAN_HAS_BLACKLIST
TEST(AddressSanitizer, IgnoreTest) {
int *x = Ident(new int);
@ -244,41 +284,6 @@ TEST(AddressSanitizer, SignalTest) {
} // namespace
#endif
static void MallocStress(size_t n) {
uint32_t seed = my_rand();
for (size_t iter = 0; iter < 10; iter++) {
vector<void *> vec;
for (size_t i = 0; i < n; i++) {
if ((i % 3) == 0) {
if (vec.empty()) continue;
size_t idx = my_rand_r(&seed) % vec.size();
void *ptr = vec[idx];
vec[idx] = vec.back();
vec.pop_back();
free_aaa(ptr);
} else {
size_t size = my_rand_r(&seed) % 1000 + 1;
#ifndef __APPLE__
size_t alignment = 1 << (my_rand_r(&seed) % 7 + 3);
char *ptr = (char*)memalign_aaa(alignment, size);
#else
char *ptr = (char*) malloc_aaa(size);
#endif
vec.push_back(ptr);
ptr[0] = 0;
ptr[size-1] = 0;
ptr[size/2] = 0;
}
}
for (size_t i = 0; i < vec.size(); i++)
free_aaa(vec[i]);
}
}
TEST(AddressSanitizer, MallocStressTest) {
MallocStress((ASAN_LOW_MEMORY) ? 20000 : 200000);
}
static void TestLargeMalloc(size_t size) {
char buff[1024];
sprintf(buff, "is located 1 bytes to the left of %lu-byte", (long)size);
@ -286,28 +291,21 @@ static void TestLargeMalloc(size_t size) {
}
TEST(AddressSanitizer, LargeMallocTest) {
for (int i = 113; i < (1 << 28); i = i * 2 + 13) {
const int max_size = (SANITIZER_WORDSIZE == 32) ? 1 << 26 : 1 << 28;
for (int i = 113; i < max_size; i = i * 2 + 13) {
TestLargeMalloc(i);
}
}
#if ASAN_LOW_MEMORY != 1
TEST(AddressSanitizer, HugeMallocTest) {
#ifdef __APPLE__
// It was empirically found out that 1215 megabytes is the maximum amount of
// memory available to the process under AddressSanitizer on 32-bit Mac 10.6.
// 32-bit Mac 10.7 gives even less (< 1G).
// (the libSystem malloc() allows allocating up to 2300 megabytes without
// ASan).
size_t n_megs = SANITIZER_WORDSIZE == 32 ? 500 : 4100;
#else
size_t n_megs = SANITIZER_WORDSIZE == 32 ? 2600 : 4100;
#endif
TestLargeMalloc(n_megs << 20);
if (SANITIZER_WORDSIZE != 64 || ASAN_AVOID_EXPENSIVE_TESTS) return;
size_t n_megs = 4100;
EXPECT_DEATH(Ident((char*)malloc(n_megs << 20))[-1] = 0,
"is located 1 bytes to the left|"
"AddressSanitizer failed to allocate");
}
#endif
#ifndef __APPLE__
#if SANITIZER_TEST_HAS_MEMALIGN
void MemalignRun(size_t align, size_t size, int idx) {
char *p = (char *)memalign(align, size);
Ident(p)[idx] = 0;
@ -323,20 +321,7 @@ TEST(AddressSanitizer, memalign) {
"is located 1 bytes to the right");
}
}
#endif
TEST(AddressSanitizer, ThreadedMallocStressTest) {
const int kNumThreads = 4;
const int kNumIterations = (ASAN_LOW_MEMORY) ? 10000 : 100000;
pthread_t t[kNumThreads];
for (int i = 0; i < kNumThreads; i++) {
PTHREAD_CREATE(&t[i], 0, (void* (*)(void *x))MallocStress,
(void*)kNumIterations);
}
for (int i = 0; i < kNumThreads; i++) {
PTHREAD_JOIN(t[i], 0);
}
}
#endif // SANITIZER_TEST_HAS_MEMALIGN
void *ManyThreadsWorker(void *a) {
for (int iter = 0; iter < 100; iter++) {
@ -377,17 +362,30 @@ TEST(AddressSanitizer, ReallocTest) {
free(ptr2);
}
TEST(AddressSanitizer, ReallocFreedPointerTest) {
void *ptr = Ident(malloc(42));
ASSERT_TRUE(NULL != ptr);
free(ptr);
EXPECT_DEATH(ptr = realloc(ptr, 77), "attempting double-free");
}
TEST(AddressSanitizer, ReallocInvalidPointerTest) {
void *ptr = Ident(malloc(42));
EXPECT_DEATH(ptr = realloc((int*)ptr + 1, 77), "attempting free.*not malloc");
free(ptr);
}
TEST(AddressSanitizer, ZeroSizeMallocTest) {
// Test that malloc(0) and similar functions don't return NULL.
void *ptr = Ident(malloc(0));
EXPECT_TRUE(NULL != ptr);
free(ptr);
#if !defined(__APPLE__) && !defined(ANDROID) && !defined(__ANDROID__)
#if SANITIZER_TEST_HAS_POSIX_MEMALIGN
int pm_res = posix_memalign(&ptr, 1<<20, 0);
EXPECT_EQ(0, pm_res);
EXPECT_TRUE(NULL != ptr);
free(ptr);
#endif
#endif // SANITIZER_TEST_HAS_POSIX_MEMALIGN
int *int_ptr = new int[0];
int *int_ptr2 = new int[0];
EXPECT_TRUE(NULL != int_ptr);
@ -397,7 +395,7 @@ TEST(AddressSanitizer, ZeroSizeMallocTest) {
delete[] int_ptr2;
}
#ifndef __APPLE__
#if SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE
static const char *kMallocUsableSizeErrorMsg =
"AddressSanitizer: attempting to call malloc_usable_size()";
@ -413,8 +411,9 @@ TEST(AddressSanitizer, MallocUsableSizeTest) {
kMallocUsableSizeErrorMsg);
free(array);
EXPECT_DEATH(malloc_usable_size(array), kMallocUsableSizeErrorMsg);
delete int_ptr;
}
#endif
#endif // SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE
void WrongFree() {
int *x = (int*)malloc(100 * sizeof(int));
@ -423,10 +422,14 @@ void WrongFree() {
free(x + 1);
}
#if !defined(_WIN32) // FIXME: This should be a lit test.
TEST(AddressSanitizer, WrongFreeTest) {
EXPECT_DEATH(WrongFree(),
"ERROR: AddressSanitizer: attempting free.*not malloc");
EXPECT_DEATH(WrongFree(), ASAN_PCRE_DOTALL
"ERROR: AddressSanitizer: attempting free.*not malloc"
".*is located 4 bytes inside of 400-byte region"
".*allocated by thread");
}
#endif
void DoubleFree() {
int *x = (int*)malloc(100 * sizeof(int));
@ -437,6 +440,7 @@ void DoubleFree() {
abort();
}
#if !defined(_WIN32) // FIXME: This should be a lit test.
TEST(AddressSanitizer, DoubleFreeTest) {
EXPECT_DEATH(DoubleFree(), ASAN_PCRE_DOTALL
"ERROR: AddressSanitizer: attempting double-free"
@ -444,20 +448,22 @@ TEST(AddressSanitizer, DoubleFreeTest) {
".*freed by thread T0 here"
".*previously allocated by thread T0 here");
}
#endif
template<int kSize>
NOINLINE void SizedStackTest() {
char a[kSize];
char *A = Ident((char*)&a);
const char *expected_death = "AddressSanitizer: stack-buffer-";
for (size_t i = 0; i < kSize; i++)
A[i] = i;
EXPECT_DEATH(A[-1] = 0, "");
EXPECT_DEATH(A[-20] = 0, "");
EXPECT_DEATH(A[-31] = 0, "");
EXPECT_DEATH(A[kSize] = 0, "");
EXPECT_DEATH(A[kSize + 1] = 0, "");
EXPECT_DEATH(A[kSize + 10] = 0, "");
EXPECT_DEATH(A[kSize + 31] = 0, "");
EXPECT_DEATH(A[-1] = 0, expected_death);
EXPECT_DEATH(A[-5] = 0, expected_death);
EXPECT_DEATH(A[kSize] = 0, expected_death);
EXPECT_DEATH(A[kSize + 1] = 0, expected_death);
EXPECT_DEATH(A[kSize + 5] = 0, expected_death);
if (kSize > 16)
EXPECT_DEATH(A[kSize + 31] = 0, expected_death);
}
TEST(AddressSanitizer, SimpleStackTest) {
@ -478,6 +484,9 @@ TEST(AddressSanitizer, SimpleStackTest) {
SizedStackTest<128>();
}
#if !defined(_WIN32)
// FIXME: It's a bit hard to write multi-line death test expectations
// in a portable way. Anyways, this should just be turned into a lit test.
TEST(AddressSanitizer, ManyStackObjectsTest) {
char XXX[10];
char YYY[20];
@ -486,6 +495,47 @@ TEST(AddressSanitizer, ManyStackObjectsTest) {
Ident(YYY);
EXPECT_DEATH(Ident(ZZZ)[-1] = 0, ASAN_PCRE_DOTALL "XXX.*YYY.*ZZZ");
}
#endif
#if 0 // This test requires online symbolizer.
// Moved to lit_tests/stack-oob-frames.cc.
// Reenable here once we have online symbolizer by default.
NOINLINE static void Frame0(int frame, char *a, char *b, char *c) {
char d[4] = {0};
char *D = Ident(d);
switch (frame) {
case 3: a[5]++; break;
case 2: b[5]++; break;
case 1: c[5]++; break;
case 0: D[5]++; break;
}
}
NOINLINE static void Frame1(int frame, char *a, char *b) {
char c[4] = {0}; Frame0(frame, a, b, c);
break_optimization(0);
}
NOINLINE static void Frame2(int frame, char *a) {
char b[4] = {0}; Frame1(frame, a, b);
break_optimization(0);
}
NOINLINE static void Frame3(int frame) {
char a[4] = {0}; Frame2(frame, a);
break_optimization(0);
}
TEST(AddressSanitizer, GuiltyStackFrame0Test) {
EXPECT_DEATH(Frame3(0), "located .*in frame <.*Frame0");
}
TEST(AddressSanitizer, GuiltyStackFrame1Test) {
EXPECT_DEATH(Frame3(1), "located .*in frame <.*Frame1");
}
TEST(AddressSanitizer, GuiltyStackFrame2Test) {
EXPECT_DEATH(Frame3(2), "located .*in frame <.*Frame2");
}
TEST(AddressSanitizer, GuiltyStackFrame3Test) {
EXPECT_DEATH(Frame3(3), "located .*in frame <.*Frame3");
}
#endif
NOINLINE void LongJmpFunc1(jmp_buf buf) {
// create three red zones for these two stack objects.
@ -498,6 +548,24 @@ NOINLINE void LongJmpFunc1(jmp_buf buf) {
longjmp(buf, 1);
}
NOINLINE void TouchStackFunc() {
int a[100]; // long array will intersect with redzones from LongJmpFunc1.
int *A = Ident(a);
for (int i = 0; i < 100; i++)
A[i] = i*i;
}
// Test that we handle longjmp and do not report false positives on stack.
TEST(AddressSanitizer, LongJmpTest) {
static jmp_buf buf;
if (!setjmp(buf)) {
LongJmpFunc1(buf);
} else {
TouchStackFunc();
}
}
#if !defined(_WIN32) // Only basic longjmp is available on Windows.
NOINLINE void BuiltinLongJmpFunc1(jmp_buf buf) {
// create three red zones for these two stack objects.
int a;
@ -531,25 +599,10 @@ NOINLINE void SigLongJmpFunc1(sigjmp_buf buf) {
siglongjmp(buf, 1);
}
NOINLINE void TouchStackFunc() {
int a[100]; // long array will intersect with redzones from LongJmpFunc1.
int *A = Ident(a);
for (int i = 0; i < 100; i++)
A[i] = i*i;
}
// Test that we handle longjmp and do not report fals positives on stack.
TEST(AddressSanitizer, LongJmpTest) {
static jmp_buf buf;
if (!setjmp(buf)) {
LongJmpFunc1(buf);
} else {
TouchStackFunc();
}
}
#if not defined(__ANDROID__)
#if !defined(__ANDROID__) && \
!defined(__powerpc64__) && !defined(__powerpc__)
// Does not work on Power:
// https://code.google.com/p/address-sanitizer/issues/detail?id=185
TEST(AddressSanitizer, BuiltinLongJmpTest) {
static jmp_buf buf;
if (!__builtin_setjmp((void**)buf)) {
@ -558,7 +611,8 @@ TEST(AddressSanitizer, BuiltinLongJmpTest) {
TouchStackFunc();
}
}
#endif // not defined(__ANDROID__)
#endif // !defined(__ANDROID__) && !defined(__powerpc64__) &&
// !defined(__powerpc__)
TEST(AddressSanitizer, UnderscopeLongJmpTest) {
static jmp_buf buf;
@ -577,8 +631,10 @@ TEST(AddressSanitizer, SigLongJmpTest) {
TouchStackFunc();
}
}
#endif
#ifdef __EXCEPTIONS
// FIXME: Why does clang-cl define __EXCEPTIONS?
#if defined(__EXCEPTIONS) && !defined(_WIN32)
NOINLINE void ThrowFunc() {
// create three red zones for these two stack objects.
int a;
@ -626,7 +682,8 @@ TEST(AddressSanitizer, ThreadStackReuseTest) {
PTHREAD_JOIN(t, 0);
}
#if defined(__i386__) || defined(__x86_64__)
#if defined(__i686__) || defined(__x86_64__)
#include <emmintrin.h>
TEST(AddressSanitizer, Store128Test) {
char *a = Ident((char*)malloc(Ident(12)));
char *p = a;
@ -644,11 +701,19 @@ TEST(AddressSanitizer, Store128Test) {
}
#endif
// FIXME: All tests that use this function should be turned into lit tests.
string RightOOBErrorMessage(int oob_distance, bool is_write) {
assert(oob_distance >= 0);
char expected_str[100];
sprintf(expected_str, ASAN_PCRE_DOTALL "%s.*located %d bytes to the right",
is_write ? "WRITE" : "READ", oob_distance);
sprintf(expected_str, ASAN_PCRE_DOTALL
#if !GTEST_USES_SIMPLE_RE
"buffer-overflow.*%s.*"
#endif
"located %d bytes to the right",
#if !GTEST_USES_SIMPLE_RE
is_write ? "WRITE" : "READ",
#endif
oob_distance);
return string(expected_str);
}
@ -660,11 +725,19 @@ string RightOOBReadMessage(int oob_distance) {
return RightOOBErrorMessage(oob_distance, /*is_write*/false);
}
// FIXME: All tests that use this function should be turned into lit tests.
string LeftOOBErrorMessage(int oob_distance, bool is_write) {
assert(oob_distance > 0);
char expected_str[100];
sprintf(expected_str, ASAN_PCRE_DOTALL "%s.*located %d bytes to the left",
is_write ? "WRITE" : "READ", oob_distance);
sprintf(expected_str,
#if !GTEST_USES_SIMPLE_RE
ASAN_PCRE_DOTALL "%s.*"
#endif
"located %d bytes to the left",
#if !GTEST_USES_SIMPLE_RE
is_write ? "WRITE" : "READ",
#endif
oob_distance);
return string(expected_str);
}
@ -818,6 +891,7 @@ void ThreadedTestSpawn() {
PTHREAD_JOIN(t, 0);
}
#if !defined(_WIN32) // FIXME: This should be a lit test.
TEST(AddressSanitizer, ThreadedTest) {
EXPECT_DEATH(ThreadedTestSpawn(),
ASAN_PCRE_DOTALL
@ -825,6 +899,7 @@ TEST(AddressSanitizer, ThreadedTest) {
".*Thread T.*created"
".*Thread T.*created");
}
#endif
void *ThreadedTestFunc(void *unused) {
// Check if prctl(PR_SET_NAME) is supported. Return if not.
@ -855,7 +930,11 @@ TEST(AddressSanitizer, ShadowGapTest) {
#if SANITIZER_WORDSIZE == 32
char *addr = (char*)0x22000000;
#else
# if defined(__powerpc64__)
char *addr = (char*)0x024000800000;
# else
char *addr = (char*)0x0000100000080000;
# endif
#endif
EXPECT_DEATH(*addr = 1, "AddressSanitizer: SEGV on unknown");
}
@ -1015,7 +1094,8 @@ TEST(AddressSanitizer, PthreadExitTest) {
}
}
#ifdef __EXCEPTIONS
// FIXME: Why does clang-cl define __EXCEPTIONS?
#if defined(__EXCEPTIONS) && !defined(_WIN32)
NOINLINE static void StackReuseAndException() {
int large_stack[1000];
Ident(large_stack);
@ -1033,12 +1113,14 @@ TEST(AddressSanitizer, DISABLED_StressStackReuseAndExceptionsTest) {
}
#endif
#if !defined(_WIN32)
TEST(AddressSanitizer, MlockTest) {
EXPECT_EQ(0, mlockall(MCL_CURRENT));
EXPECT_EQ(0, mlock((void*)0x12345, 0x5678));
EXPECT_EQ(0, munlockall());
EXPECT_EQ(0, munlock((void*)0x987, 0x654));
}
#endif
struct LargeStruct {
int foo[100];
@ -1051,19 +1133,26 @@ TEST(AddressSanitizer, LargeStructCopyTest) {
*Ident(&a) = *Ident(&a);
}
ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS
static void NoAddressSafety() {
ATTRIBUTE_NO_SANITIZE_ADDRESS
static void NoSanitizeAddress() {
char *foo = new char[10];
Ident(foo)[10] = 0;
delete [] foo;
}
TEST(AddressSanitizer, AttributeNoAddressSafetyTest) {
Ident(NoAddressSafety)();
TEST(AddressSanitizer, AttributeNoSanitizeAddressTest) {
Ident(NoSanitizeAddress)();
}
// It doesn't work on Android, as calls to new/delete go through malloc/free.
#if !defined(ANDROID) && !defined(__ANDROID__)
// The new/delete/etc mismatch checks don't work on Android,
// as calls to new/delete go through malloc/free.
// OS X support is tracked here:
// https://code.google.com/p/address-sanitizer/issues/detail?id=131
// Windows support is tracked here:
// https://code.google.com/p/address-sanitizer/issues/detail?id=309
#if !defined(ANDROID) && !defined(__ANDROID__) && \
!defined(__APPLE__) && \
!defined(_WIN32)
static string MismatchStr(const string &str) {
return string("AddressSanitizer: alloc-dealloc-mismatch \\(") + str;
}
@ -1177,3 +1266,18 @@ TEST(AddressSanitizer, LongDoubleNegativeTest) {
memcpy(Ident(&a), Ident(&b), sizeof(long double));
memcpy(Ident(&c), Ident(&b), sizeof(long double));
}
#if !defined(_WIN32)
TEST(AddressSanitizer, pthread_getschedparam) {
int policy;
struct sched_param param;
EXPECT_DEATH(
pthread_getschedparam(pthread_self(), &policy, Ident(&param) + 2),
"AddressSanitizer: stack-buffer-.*flow");
EXPECT_DEATH(
pthread_getschedparam(pthread_self(), Ident(&policy) - 1, &param),
"AddressSanitizer: stack-buffer-.*flow");
int res = pthread_getschedparam(pthread_self(), &policy, &param);
ASSERT_EQ(0, res);
}
#endif

View file

@ -19,12 +19,6 @@
#include <string>
#include <map>
#if ASAN_USE_DEJAGNU_GTEST
# include "dejagnu-gtest.h"
#else
# include "gtest/gtest.h"
#endif
using std::string;
using std::vector;
using std::map;
@ -42,11 +36,11 @@ using std::map;
#endif
#ifndef ASAN_NEEDS_SEGV
# error "please define ASAN_NEEDS_SEGV"
#endif
#ifndef ASAN_LOW_MEMORY
# define ASAN_LOW_MEMORY 0
# if defined(_WIN32)
# define ASAN_NEEDS_SEGV 0
# else
# define ASAN_NEEDS_SEGV 1
# endif
#endif
#ifndef ASAN_AVOID_EXPENSIVE_TESTS

View file

@ -12,24 +12,28 @@
#ifndef ASAN_TEST_UTILS_H
#define ASAN_TEST_UTILS_H
#if !defined(ASAN_EXTERNAL_TEST_CONFIG)
#if !defined(SANITIZER_EXTERNAL_TEST_CONFIG)
# define INCLUDED_FROM_ASAN_TEST_UTILS_H
# include "asan_test_config.h"
# undef INCLUDED_FROM_ASAN_TEST_UTILS_H
#endif
#include "sanitizer_test_utils.h"
#include "sanitizer_pthread_wrappers.h"
#include <stdio.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <strings.h>
#include <pthread.h>
#include <stdint.h>
#include <setjmp.h>
#include <assert.h>
#include <algorithm>
#include <sys/mman.h>
#if !defined(_WIN32)
# include <strings.h>
# include <sys/mman.h>
# include <setjmp.h>
#endif
#ifdef __linux__
# include <sys/prctl.h>
@ -39,18 +43,10 @@
#include <unistd.h>
#endif
#if defined(__i386__) || defined(__x86_64__)
#include <emmintrin.h>
#endif
#ifndef __APPLE__
#if !defined(__APPLE__) && !defined(__FreeBSD__)
#include <malloc.h>
#endif
// Check that pthread_create/pthread_join return success.
#define PTHREAD_CREATE(a, b, c, d) ASSERT_EQ(0, pthread_create(a, b, c, d))
#define PTHREAD_JOIN(a, b) ASSERT_EQ(0, pthread_join(a, b))
#if ASAN_HAS_EXCEPTIONS
# define ASAN_THROW(x) throw (x)
#else

View file

@ -0,0 +1,64 @@
//===-- sanitizer_pthread_wrappers.h ----------------------------*- C++ -*-===//
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file is a part of *Sanitizer runtime.
// It provides handy wrappers for thread manipulation, that:
// a) assert on any failure rather than returning an error code
// b) defines pthread-like interface on platforms where where <pthread.h>
// is not supplied by default.
//
//===----------------------------------------------------------------------===//
#ifndef SANITIZER_PTHREAD_WRAPPERS_H
#define SANITIZER_PTHREAD_WRAPPERS_H
#include "sanitizer_test_utils.h"
#if !defined(_WIN32)
# include <pthread.h>
// Simply forward the arguments and check that the pthread functions succeed.
# define PTHREAD_CREATE(a, b, c, d) ASSERT_EQ(0, pthread_create(a, b, c, d))
# define PTHREAD_JOIN(a, b) ASSERT_EQ(0, pthread_join(a, b))
#else
typedef HANDLE pthread_t;
struct PthreadHelperCreateThreadInfo {
void *(*start_routine)(void *);
void *arg;
};
inline DWORD WINAPI PthreadHelperThreadProc(void *arg) {
PthreadHelperCreateThreadInfo *start_data =
reinterpret_cast<PthreadHelperCreateThreadInfo*>(arg);
void *ret = (start_data->start_routine)(start_data->arg);
delete start_data;
return (DWORD)ret;
}
inline void PTHREAD_CREATE(pthread_t *thread, void *attr,
void *(*start_routine)(void *), void *arg) {
ASSERT_EQ(0, attr) << "Thread attributes are not supported yet.";
PthreadHelperCreateThreadInfo *data = new PthreadHelperCreateThreadInfo;
data->start_routine = start_routine;
data->arg = arg;
*thread = CreateThread(0, 0, PthreadHelperThreadProc, data, 0, 0);
ASSERT_NE(nullptr, *thread) << "Failed to create a thread.";
}
inline void PTHREAD_JOIN(pthread_t thread, void **value_ptr) {
ASSERT_EQ(0, value_ptr) << "Nonzero value_ptr is not supported yet.";
ASSERT_EQ(WAIT_OBJECT_0, WaitForSingleObject(thread, INFINITE));
ASSERT_NE(0, CloseHandle(thread));
}
inline void pthread_exit(void *retval) {
ASSERT_EQ(0, retval) << "Nonzero retval is not supported yet.";
ExitThread((DWORD)retval);
}
#endif // _WIN32
#endif // SANITIZER_PTHREAD_WRAPPERS_H

View file

@ -0,0 +1,28 @@
//===-- sanitizer_test_config.h ---------------------------------*- C++ -*-===//
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file is a part of *Sanitizer runtime.
//
//===----------------------------------------------------------------------===//
#if !defined(INCLUDED_FROM_SANITIZER_TEST_UTILS_H)
# error "This file should be included into sanitizer_test_utils.h only"
#endif
#ifndef SANITIZER_TEST_CONFIG_H
#define SANITIZER_TEST_CONFIG_H
#include <vector>
#include <string>
#include <map>
#if SANITIZER_USE_DEJAGNU_GTEST
# include "dejagnu-gtest.h"
#else
# include "gtest/gtest.h"
#endif
#endif // SANITIZER_TEST_CONFIG_H

View file

@ -14,32 +14,47 @@
#define SANITIZER_TEST_UTILS_H
#if defined(_WIN32)
typedef unsigned __int8 uint8_t;
typedef unsigned __int16 uint16_t;
typedef unsigned __int32 uint32_t;
typedef unsigned __int64 uint64_t;
typedef __int8 int8_t;
typedef __int16 int16_t;
typedef __int32 int32_t;
typedef __int64 int64_t;
# define NOINLINE __declspec(noinline)
# define USED
#else // defined(_WIN32)
# define NOINLINE __attribute__((noinline))
# define USED __attribute__((used))
// <windows.h> should always be the first include on Windows.
# include <windows.h>
// MSVS headers define max/min as macros, so std::max/min gets crazy.
# undef max
# undef min
#endif
#if !defined(SANITIZER_EXTERNAL_TEST_CONFIG)
# define INCLUDED_FROM_SANITIZER_TEST_UTILS_H
# include "sanitizer_test_config.h"
# undef INCLUDED_FROM_SANITIZER_TEST_UTILS_H
#endif
#include <stdint.h>
#endif // defined(_WIN32)
#if defined(_MSC_VER)
# define NOINLINE __declspec(noinline)
#else // defined(_MSC_VER)
# define NOINLINE __attribute__((noinline))
#endif // defined(_MSC_VER)
#if !defined(_MSC_VER) || defined(__clang__)
# define UNUSED __attribute__((unused))
# define USED __attribute__((used))
#else
# define UNUSED
# define USED
#endif
#if !defined(__has_feature)
#define __has_feature(x) 0
#endif
#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
# define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS \
#ifndef ATTRIBUTE_NO_SANITIZE_ADDRESS
# if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
# define ATTRIBUTE_NO_SANITIZE_ADDRESS \
__attribute__((no_sanitize_address))
#else
# define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS
#endif
# else
# define ATTRIBUTE_NO_SANITIZE_ADDRESS
# endif
#endif // ATTRIBUTE_NO_SANITIZE_ADDRESS
#if __LP64__ || defined(_WIN64)
# define SANITIZER_WORDSIZE 64
@ -49,7 +64,9 @@ typedef __int64 int64_t;
// Make the compiler thinks that something is going on there.
inline void break_optimization(void *arg) {
#if !defined(_WIN32) || defined(__clang__)
__asm__ __volatile__("" : : "r" (arg) : "memory");
#endif
}
// This function returns its parameter but in such a way that compiler
@ -74,5 +91,28 @@ static inline uint32_t my_rand() {
return my_rand_r(&global_seed);
}
// Set availability of platform-specific functions.
#if !defined(__APPLE__) && !defined(ANDROID) && !defined(__ANDROID__) && !defined(_WIN32)
# define SANITIZER_TEST_HAS_POSIX_MEMALIGN 1
#else
# define SANITIZER_TEST_HAS_POSIX_MEMALIGN 0
#endif
#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(_WIN32)
# define SANITIZER_TEST_HAS_MEMALIGN 1
# define SANITIZER_TEST_HAS_PVALLOC 1
# define SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE 1
#else
# define SANITIZER_TEST_HAS_MEMALIGN 0
# define SANITIZER_TEST_HAS_PVALLOC 0
# define SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE 0
#endif
#if !defined(__APPLE__)
# define SANITIZER_TEST_HAS_STRNLEN 1
#else
# define SANITIZER_TEST_HAS_STRNLEN 0
#endif
#endif // SANITIZER_TEST_UTILS_H