13cab2bb3Spatrick //===-- asan_test.cpp -----------------------------------------------------===//
23cab2bb3Spatrick //
33cab2bb3Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
43cab2bb3Spatrick // See https://llvm.org/LICENSE.txt for license information.
53cab2bb3Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63cab2bb3Spatrick //
73cab2bb3Spatrick //===----------------------------------------------------------------------===//
83cab2bb3Spatrick //
93cab2bb3Spatrick // This file is a part of AddressSanitizer, an address sanity checker.
103cab2bb3Spatrick //
113cab2bb3Spatrick //===----------------------------------------------------------------------===//
123cab2bb3Spatrick #include "asan_test_utils.h"
133cab2bb3Spatrick
143cab2bb3Spatrick #include <errno.h>
153cab2bb3Spatrick #include <stdarg.h>
163cab2bb3Spatrick
173cab2bb3Spatrick #ifdef _LIBCPP_GET_C_LOCALE
183cab2bb3Spatrick #define SANITIZER_GET_C_LOCALE _LIBCPP_GET_C_LOCALE
193cab2bb3Spatrick #else
203cab2bb3Spatrick #if defined(__FreeBSD__)
213cab2bb3Spatrick #define SANITIZER_GET_C_LOCALE 0
223cab2bb3Spatrick #elif defined(__NetBSD__)
233cab2bb3Spatrick #define SANITIZER_GET_C_LOCALE LC_C_LOCALE
243cab2bb3Spatrick #endif
253cab2bb3Spatrick #endif
263cab2bb3Spatrick
273cab2bb3Spatrick #if defined(__sun__) && defined(__svr4__)
283cab2bb3Spatrick using std::_setjmp;
293cab2bb3Spatrick using std::_longjmp;
303cab2bb3Spatrick #endif
313cab2bb3Spatrick
malloc_fff(size_t size)323cab2bb3Spatrick NOINLINE void *malloc_fff(size_t size) {
333cab2bb3Spatrick void *res = malloc/**/(size); break_optimization(0); return res;}
malloc_eee(size_t size)343cab2bb3Spatrick NOINLINE void *malloc_eee(size_t size) {
353cab2bb3Spatrick void *res = malloc_fff(size); break_optimization(0); return res;}
malloc_ddd(size_t size)363cab2bb3Spatrick NOINLINE void *malloc_ddd(size_t size) {
373cab2bb3Spatrick void *res = malloc_eee(size); break_optimization(0); return res;}
malloc_ccc(size_t size)383cab2bb3Spatrick NOINLINE void *malloc_ccc(size_t size) {
393cab2bb3Spatrick void *res = malloc_ddd(size); break_optimization(0); return res;}
malloc_bbb(size_t size)403cab2bb3Spatrick NOINLINE void *malloc_bbb(size_t size) {
413cab2bb3Spatrick void *res = malloc_ccc(size); break_optimization(0); return res;}
malloc_aaa(size_t size)423cab2bb3Spatrick NOINLINE void *malloc_aaa(size_t size) {
433cab2bb3Spatrick void *res = malloc_bbb(size); break_optimization(0); return res;}
443cab2bb3Spatrick
free_ccc(void * p)453cab2bb3Spatrick NOINLINE void free_ccc(void *p) { free(p); break_optimization(0);}
free_bbb(void * p)463cab2bb3Spatrick NOINLINE void free_bbb(void *p) { free_ccc(p); break_optimization(0);}
free_aaa(void * p)473cab2bb3Spatrick NOINLINE void free_aaa(void *p) { free_bbb(p); break_optimization(0);}
483cab2bb3Spatrick
493cab2bb3Spatrick template<typename T>
uaf_test(int size,int off)503cab2bb3Spatrick NOINLINE void uaf_test(int size, int off) {
513cab2bb3Spatrick void *p = malloc_aaa(size);
523cab2bb3Spatrick free_aaa(p);
533cab2bb3Spatrick for (int i = 1; i < 100; i++)
543cab2bb3Spatrick free_aaa(malloc_aaa(i));
553cab2bb3Spatrick fprintf(stderr, "writing %ld byte(s) at %p with offset %d\n",
563cab2bb3Spatrick (long)sizeof(T), p, off);
573cab2bb3Spatrick asan_write((T *)((char *)p + off));
583cab2bb3Spatrick }
593cab2bb3Spatrick
TEST(AddressSanitizer,HasFeatureAddressSanitizerTest)603cab2bb3Spatrick TEST(AddressSanitizer, HasFeatureAddressSanitizerTest) {
613cab2bb3Spatrick #if defined(__has_feature) && __has_feature(address_sanitizer)
623cab2bb3Spatrick bool asan = 1;
633cab2bb3Spatrick #elif defined(__SANITIZE_ADDRESS__)
643cab2bb3Spatrick bool asan = 1;
653cab2bb3Spatrick #else
663cab2bb3Spatrick bool asan = 0;
673cab2bb3Spatrick #endif
683cab2bb3Spatrick EXPECT_EQ(true, asan);
693cab2bb3Spatrick }
703cab2bb3Spatrick
TEST(AddressSanitizer,SimpleDeathTest)713cab2bb3Spatrick TEST(AddressSanitizer, SimpleDeathTest) {
723cab2bb3Spatrick EXPECT_DEATH(exit(1), "");
733cab2bb3Spatrick }
743cab2bb3Spatrick
TEST(AddressSanitizer,VariousMallocsTest)753cab2bb3Spatrick TEST(AddressSanitizer, VariousMallocsTest) {
763cab2bb3Spatrick int *a = (int*)malloc(100 * sizeof(int));
773cab2bb3Spatrick a[50] = 0;
783cab2bb3Spatrick free(a);
793cab2bb3Spatrick
803cab2bb3Spatrick int *r = (int*)malloc(10);
813cab2bb3Spatrick r = (int*)realloc(r, 2000 * sizeof(int));
823cab2bb3Spatrick r[1000] = 0;
833cab2bb3Spatrick free(r);
843cab2bb3Spatrick
853cab2bb3Spatrick int *b = new int[100];
863cab2bb3Spatrick b[50] = 0;
873cab2bb3Spatrick delete [] b;
883cab2bb3Spatrick
893cab2bb3Spatrick int *c = new int;
903cab2bb3Spatrick *c = 0;
913cab2bb3Spatrick delete c;
923cab2bb3Spatrick
933cab2bb3Spatrick #if SANITIZER_TEST_HAS_POSIX_MEMALIGN
943cab2bb3Spatrick void *pm = 0;
953cab2bb3Spatrick // Valid allocation.
963cab2bb3Spatrick int pm_res = posix_memalign(&pm, kPageSize, kPageSize);
973cab2bb3Spatrick EXPECT_EQ(0, pm_res);
983cab2bb3Spatrick EXPECT_NE(nullptr, pm);
993cab2bb3Spatrick free(pm);
1003cab2bb3Spatrick #endif // SANITIZER_TEST_HAS_POSIX_MEMALIGN
1013cab2bb3Spatrick
1023cab2bb3Spatrick #if SANITIZER_TEST_HAS_MEMALIGN
1033cab2bb3Spatrick int *ma = (int*)memalign(kPageSize, kPageSize);
1043cab2bb3Spatrick EXPECT_EQ(0U, (uintptr_t)ma % kPageSize);
1053cab2bb3Spatrick ma[123] = 0;
1063cab2bb3Spatrick free(ma);
1073cab2bb3Spatrick #endif // SANITIZER_TEST_HAS_MEMALIGN
1083cab2bb3Spatrick }
1093cab2bb3Spatrick
TEST(AddressSanitizer,CallocTest)1103cab2bb3Spatrick TEST(AddressSanitizer, CallocTest) {
1113cab2bb3Spatrick int *a = (int*)calloc(100, sizeof(int));
1123cab2bb3Spatrick EXPECT_EQ(0, a[10]);
1133cab2bb3Spatrick free(a);
1143cab2bb3Spatrick }
1153cab2bb3Spatrick
TEST(AddressSanitizer,CallocReturnsZeroMem)1163cab2bb3Spatrick TEST(AddressSanitizer, CallocReturnsZeroMem) {
1173cab2bb3Spatrick size_t sizes[] = {16, 1000, 10000, 100000, 2100000};
1183cab2bb3Spatrick for (size_t s = 0; s < sizeof(sizes)/sizeof(sizes[0]); s++) {
1193cab2bb3Spatrick size_t size = sizes[s];
1203cab2bb3Spatrick for (size_t iter = 0; iter < 5; iter++) {
1213cab2bb3Spatrick char *x = Ident((char*)calloc(1, size));
1223cab2bb3Spatrick EXPECT_EQ(x[0], 0);
1233cab2bb3Spatrick EXPECT_EQ(x[size - 1], 0);
1243cab2bb3Spatrick EXPECT_EQ(x[size / 2], 0);
1253cab2bb3Spatrick EXPECT_EQ(x[size / 3], 0);
1263cab2bb3Spatrick EXPECT_EQ(x[size / 4], 0);
1273cab2bb3Spatrick memset(x, 0x42, size);
1283cab2bb3Spatrick free(Ident(x));
1293cab2bb3Spatrick #if !defined(_WIN32)
1303cab2bb3Spatrick // FIXME: OOM on Windows. We should just make this a lit test
1313cab2bb3Spatrick // with quarantine size set to 1.
1323cab2bb3Spatrick free(Ident(malloc(Ident(1 << 27)))); // Try to drain the quarantine.
1333cab2bb3Spatrick #endif
1343cab2bb3Spatrick }
1353cab2bb3Spatrick }
1363cab2bb3Spatrick }
1373cab2bb3Spatrick
1383cab2bb3Spatrick // No valloc on Windows or Android.
1393cab2bb3Spatrick #if !defined(_WIN32) && !defined(__ANDROID__)
TEST(AddressSanitizer,VallocTest)1403cab2bb3Spatrick TEST(AddressSanitizer, VallocTest) {
1413cab2bb3Spatrick void *a = valloc(100);
1423cab2bb3Spatrick EXPECT_EQ(0U, (uintptr_t)a % kPageSize);
1433cab2bb3Spatrick free(a);
1443cab2bb3Spatrick }
1453cab2bb3Spatrick #endif
1463cab2bb3Spatrick
1473cab2bb3Spatrick #if SANITIZER_TEST_HAS_PVALLOC
TEST(AddressSanitizer,PvallocTest)1483cab2bb3Spatrick TEST(AddressSanitizer, PvallocTest) {
1493cab2bb3Spatrick char *a = (char*)pvalloc(kPageSize + 100);
1503cab2bb3Spatrick EXPECT_EQ(0U, (uintptr_t)a % kPageSize);
1513cab2bb3Spatrick a[kPageSize + 101] = 1; // we should not report an error here.
1523cab2bb3Spatrick free(a);
1533cab2bb3Spatrick
1543cab2bb3Spatrick a = (char*)pvalloc(0); // pvalloc(0) should allocate at least one page.
1553cab2bb3Spatrick EXPECT_EQ(0U, (uintptr_t)a % kPageSize);
1563cab2bb3Spatrick a[101] = 1; // we should not report an error here.
1573cab2bb3Spatrick free(a);
1583cab2bb3Spatrick }
1593cab2bb3Spatrick #endif // SANITIZER_TEST_HAS_PVALLOC
1603cab2bb3Spatrick
1613cab2bb3Spatrick #if !defined(_WIN32)
1623cab2bb3Spatrick // FIXME: Use an equivalent of pthread_setspecific on Windows.
TSDWorker(void * test_key)1633cab2bb3Spatrick void *TSDWorker(void *test_key) {
1643cab2bb3Spatrick if (test_key) {
1653cab2bb3Spatrick pthread_setspecific(*(pthread_key_t*)test_key, (void*)0xfeedface);
1663cab2bb3Spatrick }
1673cab2bb3Spatrick return NULL;
1683cab2bb3Spatrick }
1693cab2bb3Spatrick
TSDDestructor(void * tsd)1703cab2bb3Spatrick void TSDDestructor(void *tsd) {
1713cab2bb3Spatrick // Spawning a thread will check that the current thread id is not -1.
1723cab2bb3Spatrick pthread_t th;
1733cab2bb3Spatrick PTHREAD_CREATE(&th, NULL, TSDWorker, NULL);
1743cab2bb3Spatrick PTHREAD_JOIN(th, NULL);
1753cab2bb3Spatrick }
1763cab2bb3Spatrick
1773cab2bb3Spatrick // This tests triggers the thread-specific data destruction fiasco which occurs
1783cab2bb3Spatrick // if we don't manage the TSD destructors ourselves. We create a new pthread
1793cab2bb3Spatrick // key with a non-NULL destructor which is likely to be put after the destructor
1803cab2bb3Spatrick // of AsanThread in the list of destructors.
1813cab2bb3Spatrick // In this case the TSD for AsanThread will be destroyed before TSDDestructor
1823cab2bb3Spatrick // is called for the child thread, and a CHECK will fail when we call
1833cab2bb3Spatrick // pthread_create() to spawn the grandchild.
TEST(AddressSanitizer,DISABLED_TSDTest)1843cab2bb3Spatrick TEST(AddressSanitizer, DISABLED_TSDTest) {
1853cab2bb3Spatrick pthread_t th;
1863cab2bb3Spatrick pthread_key_t test_key;
1873cab2bb3Spatrick pthread_key_create(&test_key, TSDDestructor);
1883cab2bb3Spatrick PTHREAD_CREATE(&th, NULL, TSDWorker, &test_key);
1893cab2bb3Spatrick PTHREAD_JOIN(th, NULL);
1903cab2bb3Spatrick pthread_key_delete(test_key);
1913cab2bb3Spatrick }
1923cab2bb3Spatrick #endif
1933cab2bb3Spatrick
TEST(AddressSanitizer,UAF_char)1943cab2bb3Spatrick TEST(AddressSanitizer, UAF_char) {
1953cab2bb3Spatrick const char *uaf_string = "AddressSanitizer:.*heap-use-after-free";
1963cab2bb3Spatrick EXPECT_DEATH(uaf_test<U1>(1, 0), uaf_string);
1973cab2bb3Spatrick EXPECT_DEATH(uaf_test<U1>(10, 0), uaf_string);
1983cab2bb3Spatrick EXPECT_DEATH(uaf_test<U1>(10, 10), uaf_string);
1993cab2bb3Spatrick EXPECT_DEATH(uaf_test<U1>(kLargeMalloc, 0), uaf_string);
2003cab2bb3Spatrick EXPECT_DEATH(uaf_test<U1>(kLargeMalloc, kLargeMalloc / 2), uaf_string);
2013cab2bb3Spatrick }
2023cab2bb3Spatrick
TEST(AddressSanitizer,UAF_long_double)2033cab2bb3Spatrick TEST(AddressSanitizer, UAF_long_double) {
2043cab2bb3Spatrick if (sizeof(long double) == sizeof(double)) return;
2053cab2bb3Spatrick long double *p = Ident(new long double[10]);
2063cab2bb3Spatrick EXPECT_DEATH(Ident(p)[12] = 0, "WRITE of size 1[026]");
2073cab2bb3Spatrick EXPECT_DEATH(Ident(p)[0] = Ident(p)[12], "READ of size 1[026]");
2083cab2bb3Spatrick delete [] Ident(p);
2093cab2bb3Spatrick }
2103cab2bb3Spatrick
2113cab2bb3Spatrick #if !defined(_WIN32)
2123cab2bb3Spatrick struct Packed5 {
2133cab2bb3Spatrick int x;
2143cab2bb3Spatrick char c;
2153cab2bb3Spatrick } __attribute__((packed));
2163cab2bb3Spatrick #else
2173cab2bb3Spatrick # pragma pack(push, 1)
2183cab2bb3Spatrick struct Packed5 {
2193cab2bb3Spatrick int x;
2203cab2bb3Spatrick char c;
2213cab2bb3Spatrick };
2223cab2bb3Spatrick # pragma pack(pop)
2233cab2bb3Spatrick #endif
2243cab2bb3Spatrick
TEST(AddressSanitizer,UAF_Packed5)2253cab2bb3Spatrick TEST(AddressSanitizer, UAF_Packed5) {
2263cab2bb3Spatrick static_assert(sizeof(Packed5) == 5, "Please check the keywords used");
2273cab2bb3Spatrick Packed5 *p = Ident(new Packed5[2]);
2283cab2bb3Spatrick EXPECT_DEATH(p[0] = p[3], "READ of size 5");
2293cab2bb3Spatrick EXPECT_DEATH(p[3] = p[0], "WRITE of size 5");
2303cab2bb3Spatrick delete [] Ident(p);
2313cab2bb3Spatrick }
2323cab2bb3Spatrick
233d89ec533Spatrick #if ASAN_HAS_IGNORELIST
TEST(AddressSanitizer,IgnoreTest)2343cab2bb3Spatrick TEST(AddressSanitizer, IgnoreTest) {
2353cab2bb3Spatrick int *x = Ident(new int);
2363cab2bb3Spatrick delete Ident(x);
2373cab2bb3Spatrick *x = 0;
2383cab2bb3Spatrick }
239d89ec533Spatrick #endif // ASAN_HAS_IGNORELIST
2403cab2bb3Spatrick
2413cab2bb3Spatrick struct StructWithBitField {
2423cab2bb3Spatrick int bf1:1;
2433cab2bb3Spatrick int bf2:1;
2443cab2bb3Spatrick int bf3:1;
2453cab2bb3Spatrick int bf4:29;
2463cab2bb3Spatrick };
2473cab2bb3Spatrick
TEST(AddressSanitizer,BitFieldPositiveTest)2483cab2bb3Spatrick TEST(AddressSanitizer, BitFieldPositiveTest) {
2493cab2bb3Spatrick StructWithBitField *x = new StructWithBitField;
2503cab2bb3Spatrick delete Ident(x);
2513cab2bb3Spatrick EXPECT_DEATH(x->bf1 = 0, "use-after-free");
2523cab2bb3Spatrick EXPECT_DEATH(x->bf2 = 0, "use-after-free");
2533cab2bb3Spatrick EXPECT_DEATH(x->bf3 = 0, "use-after-free");
2543cab2bb3Spatrick EXPECT_DEATH(x->bf4 = 0, "use-after-free");
2553cab2bb3Spatrick }
2563cab2bb3Spatrick
2573cab2bb3Spatrick struct StructWithBitFields_8_24 {
2583cab2bb3Spatrick int a:8;
2593cab2bb3Spatrick int b:24;
2603cab2bb3Spatrick };
2613cab2bb3Spatrick
TEST(AddressSanitizer,BitFieldNegativeTest)2623cab2bb3Spatrick TEST(AddressSanitizer, BitFieldNegativeTest) {
2633cab2bb3Spatrick StructWithBitFields_8_24 *x = Ident(new StructWithBitFields_8_24);
2643cab2bb3Spatrick x->a = 0;
2653cab2bb3Spatrick x->b = 0;
2663cab2bb3Spatrick delete Ident(x);
2673cab2bb3Spatrick }
2683cab2bb3Spatrick
2693cab2bb3Spatrick #if ASAN_NEEDS_SEGV
2703cab2bb3Spatrick namespace {
2713cab2bb3Spatrick
2723cab2bb3Spatrick const char kSEGVCrash[] = "AddressSanitizer: SEGV on unknown address";
2733cab2bb3Spatrick const char kOverriddenSigactionHandler[] = "Test sigaction handler\n";
2743cab2bb3Spatrick const char kOverriddenSignalHandler[] = "Test signal handler\n";
2753cab2bb3Spatrick
TEST(AddressSanitizer,WildAddressTest)2763cab2bb3Spatrick TEST(AddressSanitizer, WildAddressTest) {
2773cab2bb3Spatrick char *c = (char*)0x123;
2783cab2bb3Spatrick EXPECT_DEATH(*c = 0, kSEGVCrash);
2793cab2bb3Spatrick }
2803cab2bb3Spatrick
my_sigaction_sighandler(int,siginfo_t *,void *)2813cab2bb3Spatrick void my_sigaction_sighandler(int, siginfo_t*, void*) {
2823cab2bb3Spatrick fprintf(stderr, kOverriddenSigactionHandler);
2833cab2bb3Spatrick exit(1);
2843cab2bb3Spatrick }
2853cab2bb3Spatrick
my_signal_sighandler(int signum)2863cab2bb3Spatrick void my_signal_sighandler(int signum) {
2873cab2bb3Spatrick fprintf(stderr, kOverriddenSignalHandler);
2883cab2bb3Spatrick exit(1);
2893cab2bb3Spatrick }
2903cab2bb3Spatrick
TEST(AddressSanitizer,SignalTest)2913cab2bb3Spatrick TEST(AddressSanitizer, SignalTest) {
2923cab2bb3Spatrick struct sigaction sigact;
2933cab2bb3Spatrick memset(&sigact, 0, sizeof(sigact));
2943cab2bb3Spatrick sigact.sa_sigaction = my_sigaction_sighandler;
2953cab2bb3Spatrick sigact.sa_flags = SA_SIGINFO;
2963cab2bb3Spatrick char *c = (char *)0x123;
2973cab2bb3Spatrick
2983cab2bb3Spatrick EXPECT_DEATH(*c = 0, kSEGVCrash);
2993cab2bb3Spatrick
3003cab2bb3Spatrick // ASan should allow to set sigaction()...
3013cab2bb3Spatrick EXPECT_EQ(0, sigaction(SIGSEGV, &sigact, 0));
3023cab2bb3Spatrick #ifdef __APPLE__
3033cab2bb3Spatrick EXPECT_EQ(0, sigaction(SIGBUS, &sigact, 0));
3043cab2bb3Spatrick #endif
3053cab2bb3Spatrick EXPECT_DEATH(*c = 0, kOverriddenSigactionHandler);
3063cab2bb3Spatrick
3073cab2bb3Spatrick // ... and signal().
3083cab2bb3Spatrick EXPECT_NE(SIG_ERR, signal(SIGSEGV, my_signal_sighandler));
3093cab2bb3Spatrick EXPECT_DEATH(*c = 0, kOverriddenSignalHandler);
3103cab2bb3Spatrick }
3113cab2bb3Spatrick } // namespace
3123cab2bb3Spatrick #endif
3133cab2bb3Spatrick
TestLargeMalloc(size_t size)3143cab2bb3Spatrick static void TestLargeMalloc(size_t size) {
3153cab2bb3Spatrick char buff[1024];
316*810390e3Srobert sprintf(buff, "is located 1 bytes before %lu-byte", (long)size);
3173cab2bb3Spatrick EXPECT_DEATH(Ident((char*)malloc(size))[-1] = 0, buff);
3183cab2bb3Spatrick }
3193cab2bb3Spatrick
TEST(AddressSanitizer,LargeMallocTest)3203cab2bb3Spatrick TEST(AddressSanitizer, LargeMallocTest) {
3213cab2bb3Spatrick const int max_size = (SANITIZER_WORDSIZE == 32) ? 1 << 26 : 1 << 28;
3223cab2bb3Spatrick for (int i = 113; i < max_size; i = i * 2 + 13) {
3233cab2bb3Spatrick TestLargeMalloc(i);
3243cab2bb3Spatrick }
3253cab2bb3Spatrick }
3263cab2bb3Spatrick
3273cab2bb3Spatrick #if !GTEST_USES_SIMPLE_RE
TEST(AddressSanitizer,HugeMallocTest)3283cab2bb3Spatrick TEST(AddressSanitizer, HugeMallocTest) {
3293cab2bb3Spatrick if (SANITIZER_WORDSIZE != 64 || ASAN_AVOID_EXPENSIVE_TESTS) return;
3303cab2bb3Spatrick size_t n_megs = 4100;
3313cab2bb3Spatrick EXPECT_DEATH(Ident((char*)malloc(n_megs << 20))[-1] = 0,
332*810390e3Srobert "is located 1 bytes before|"
3333cab2bb3Spatrick "AddressSanitizer failed to allocate");
3343cab2bb3Spatrick }
3353cab2bb3Spatrick #endif
3363cab2bb3Spatrick
3373cab2bb3Spatrick #if SANITIZER_TEST_HAS_MEMALIGN
MemalignRun(size_t align,size_t size,int idx)3383cab2bb3Spatrick void MemalignRun(size_t align, size_t size, int idx) {
3393cab2bb3Spatrick char *p = (char *)memalign(align, size);
3403cab2bb3Spatrick Ident(p)[idx] = 0;
3413cab2bb3Spatrick free(p);
3423cab2bb3Spatrick }
3433cab2bb3Spatrick
TEST(AddressSanitizer,memalign)3443cab2bb3Spatrick TEST(AddressSanitizer, memalign) {
3453cab2bb3Spatrick for (int align = 16; align <= (1 << 23); align *= 2) {
3463cab2bb3Spatrick size_t size = align * 5;
3473cab2bb3Spatrick EXPECT_DEATH(MemalignRun(align, size, -1),
348*810390e3Srobert "is located 1 bytes before");
3493cab2bb3Spatrick EXPECT_DEATH(MemalignRun(align, size, size + 1),
350*810390e3Srobert "is located 1 bytes after");
3513cab2bb3Spatrick }
3523cab2bb3Spatrick }
3533cab2bb3Spatrick #endif // SANITIZER_TEST_HAS_MEMALIGN
3543cab2bb3Spatrick
ManyThreadsWorker(void * a)3553cab2bb3Spatrick void *ManyThreadsWorker(void *a) {
3563cab2bb3Spatrick for (int iter = 0; iter < 100; iter++) {
3573cab2bb3Spatrick for (size_t size = 100; size < 2000; size *= 2) {
3583cab2bb3Spatrick free(Ident(malloc(size)));
3593cab2bb3Spatrick }
3603cab2bb3Spatrick }
3613cab2bb3Spatrick return 0;
3623cab2bb3Spatrick }
3633cab2bb3Spatrick
3643cab2bb3Spatrick #if !defined(__aarch64__) && !defined(__powerpc64__)
3653cab2bb3Spatrick // FIXME: Infinite loop in AArch64 (PR24389).
3663cab2bb3Spatrick // FIXME: Also occasional hang on powerpc. Maybe same problem as on AArch64?
TEST(AddressSanitizer,ManyThreadsTest)3673cab2bb3Spatrick TEST(AddressSanitizer, ManyThreadsTest) {
3683cab2bb3Spatrick const size_t kNumThreads =
3693cab2bb3Spatrick (SANITIZER_WORDSIZE == 32 || ASAN_AVOID_EXPENSIVE_TESTS) ? 30 : 1000;
3703cab2bb3Spatrick pthread_t t[kNumThreads];
3713cab2bb3Spatrick for (size_t i = 0; i < kNumThreads; i++) {
3723cab2bb3Spatrick PTHREAD_CREATE(&t[i], 0, ManyThreadsWorker, (void*)i);
3733cab2bb3Spatrick }
3743cab2bb3Spatrick for (size_t i = 0; i < kNumThreads; i++) {
3753cab2bb3Spatrick PTHREAD_JOIN(t[i], 0);
3763cab2bb3Spatrick }
3773cab2bb3Spatrick }
3783cab2bb3Spatrick #endif
3793cab2bb3Spatrick
TEST(AddressSanitizer,ReallocTest)3803cab2bb3Spatrick TEST(AddressSanitizer, ReallocTest) {
3813cab2bb3Spatrick const int kMinElem = 5;
3823cab2bb3Spatrick int *ptr = (int*)malloc(sizeof(int) * kMinElem);
3833cab2bb3Spatrick ptr[3] = 3;
3843cab2bb3Spatrick for (int i = 0; i < 10000; i++) {
3853cab2bb3Spatrick ptr = (int*)realloc(ptr,
3863cab2bb3Spatrick (my_rand() % 1000 + kMinElem) * sizeof(int));
3873cab2bb3Spatrick EXPECT_EQ(3, ptr[3]);
3883cab2bb3Spatrick }
3893cab2bb3Spatrick free(ptr);
3903cab2bb3Spatrick // Realloc pointer returned by malloc(0).
3913cab2bb3Spatrick int *ptr2 = Ident((int*)malloc(0));
3923cab2bb3Spatrick ptr2 = Ident((int*)realloc(ptr2, sizeof(*ptr2)));
3933cab2bb3Spatrick *ptr2 = 42;
3943cab2bb3Spatrick EXPECT_EQ(42, *ptr2);
3953cab2bb3Spatrick free(ptr2);
3963cab2bb3Spatrick }
3973cab2bb3Spatrick
TEST(AddressSanitizer,ReallocFreedPointerTest)3983cab2bb3Spatrick TEST(AddressSanitizer, ReallocFreedPointerTest) {
3993cab2bb3Spatrick void *ptr = Ident(malloc(42));
4003cab2bb3Spatrick ASSERT_TRUE(NULL != ptr);
4013cab2bb3Spatrick free(ptr);
4023cab2bb3Spatrick EXPECT_DEATH(ptr = realloc(ptr, 77), "attempting double-free");
4033cab2bb3Spatrick }
4043cab2bb3Spatrick
TEST(AddressSanitizer,ReallocInvalidPointerTest)4053cab2bb3Spatrick TEST(AddressSanitizer, ReallocInvalidPointerTest) {
4063cab2bb3Spatrick void *ptr = Ident(malloc(42));
4073cab2bb3Spatrick EXPECT_DEATH(ptr = realloc((int*)ptr + 1, 77), "attempting free.*not malloc");
4083cab2bb3Spatrick free(ptr);
4093cab2bb3Spatrick }
4103cab2bb3Spatrick
TEST(AddressSanitizer,ZeroSizeMallocTest)4113cab2bb3Spatrick TEST(AddressSanitizer, ZeroSizeMallocTest) {
4123cab2bb3Spatrick // Test that malloc(0) and similar functions don't return NULL.
4133cab2bb3Spatrick void *ptr = Ident(malloc(0));
4143cab2bb3Spatrick EXPECT_TRUE(NULL != ptr);
4153cab2bb3Spatrick free(ptr);
4163cab2bb3Spatrick #if SANITIZER_TEST_HAS_POSIX_MEMALIGN
4173cab2bb3Spatrick int pm_res = posix_memalign(&ptr, 1<<20, 0);
4183cab2bb3Spatrick EXPECT_EQ(0, pm_res);
4193cab2bb3Spatrick EXPECT_TRUE(NULL != ptr);
4203cab2bb3Spatrick free(ptr);
4213cab2bb3Spatrick #endif // SANITIZER_TEST_HAS_POSIX_MEMALIGN
4223cab2bb3Spatrick int *int_ptr = new int[0];
4233cab2bb3Spatrick int *int_ptr2 = new int[0];
4243cab2bb3Spatrick EXPECT_TRUE(NULL != int_ptr);
4253cab2bb3Spatrick EXPECT_TRUE(NULL != int_ptr2);
4263cab2bb3Spatrick EXPECT_NE(int_ptr, int_ptr2);
4273cab2bb3Spatrick delete[] int_ptr;
4283cab2bb3Spatrick delete[] int_ptr2;
4293cab2bb3Spatrick }
4303cab2bb3Spatrick
4313cab2bb3Spatrick #if SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE
4323cab2bb3Spatrick static const char *kMallocUsableSizeErrorMsg =
4333cab2bb3Spatrick "AddressSanitizer: attempting to call malloc_usable_size()";
4343cab2bb3Spatrick
TEST(AddressSanitizer,MallocUsableSizeTest)4353cab2bb3Spatrick TEST(AddressSanitizer, MallocUsableSizeTest) {
4363cab2bb3Spatrick const size_t kArraySize = 100;
4373cab2bb3Spatrick char *array = Ident((char*)malloc(kArraySize));
4383cab2bb3Spatrick int *int_ptr = Ident(new int);
4393cab2bb3Spatrick EXPECT_EQ(0U, malloc_usable_size(NULL));
4403cab2bb3Spatrick EXPECT_EQ(kArraySize, malloc_usable_size(array));
4413cab2bb3Spatrick EXPECT_EQ(sizeof(int), malloc_usable_size(int_ptr));
4423cab2bb3Spatrick EXPECT_DEATH(malloc_usable_size((void*)0x123), kMallocUsableSizeErrorMsg);
4433cab2bb3Spatrick EXPECT_DEATH(malloc_usable_size(array + kArraySize / 2),
4443cab2bb3Spatrick kMallocUsableSizeErrorMsg);
4453cab2bb3Spatrick free(array);
4463cab2bb3Spatrick EXPECT_DEATH(malloc_usable_size(array), kMallocUsableSizeErrorMsg);
4473cab2bb3Spatrick delete int_ptr;
4483cab2bb3Spatrick }
4493cab2bb3Spatrick #endif // SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE
4503cab2bb3Spatrick
WrongFree()4513cab2bb3Spatrick void WrongFree() {
4523cab2bb3Spatrick int *x = (int*)malloc(100 * sizeof(int));
4533cab2bb3Spatrick // Use the allocated memory, otherwise Clang will optimize it out.
4543cab2bb3Spatrick Ident(x);
4553cab2bb3Spatrick free(x + 1);
4563cab2bb3Spatrick }
4573cab2bb3Spatrick
4583cab2bb3Spatrick #if !defined(_WIN32) // FIXME: This should be a lit test.
TEST(AddressSanitizer,WrongFreeTest)4593cab2bb3Spatrick TEST(AddressSanitizer, WrongFreeTest) {
4603cab2bb3Spatrick EXPECT_DEATH(WrongFree(), ASAN_PCRE_DOTALL
4613cab2bb3Spatrick "ERROR: AddressSanitizer: attempting free.*not malloc"
4623cab2bb3Spatrick ".*is located 4 bytes inside of 400-byte region"
4633cab2bb3Spatrick ".*allocated by thread");
4643cab2bb3Spatrick }
4653cab2bb3Spatrick #endif
4663cab2bb3Spatrick
DoubleFree()4673cab2bb3Spatrick void DoubleFree() {
4683cab2bb3Spatrick int *x = (int*)malloc(100 * sizeof(int));
4693cab2bb3Spatrick fprintf(stderr, "DoubleFree: x=%p\n", (void *)x);
4703cab2bb3Spatrick free(x);
4713cab2bb3Spatrick free(x);
4723cab2bb3Spatrick fprintf(stderr, "should have failed in the second free(%p)\n", (void *)x);
4733cab2bb3Spatrick abort();
4743cab2bb3Spatrick }
4753cab2bb3Spatrick
4763cab2bb3Spatrick #if !defined(_WIN32) // FIXME: This should be a lit test.
TEST(AddressSanitizer,DoubleFreeTest)4773cab2bb3Spatrick TEST(AddressSanitizer, DoubleFreeTest) {
4783cab2bb3Spatrick EXPECT_DEATH(DoubleFree(), ASAN_PCRE_DOTALL
4793cab2bb3Spatrick "ERROR: AddressSanitizer: attempting double-free"
4803cab2bb3Spatrick ".*is located 0 bytes inside of 400-byte region"
4813cab2bb3Spatrick ".*freed by thread T0 here"
4823cab2bb3Spatrick ".*previously allocated by thread T0 here");
4833cab2bb3Spatrick }
4843cab2bb3Spatrick #endif
4853cab2bb3Spatrick
4863cab2bb3Spatrick template<int kSize>
SizedStackTest()4873cab2bb3Spatrick NOINLINE void SizedStackTest() {
4883cab2bb3Spatrick char a[kSize];
4893cab2bb3Spatrick char *A = Ident((char*)&a);
4903cab2bb3Spatrick const char *expected_death = "AddressSanitizer: stack-buffer-";
4913cab2bb3Spatrick for (size_t i = 0; i < kSize; i++)
4923cab2bb3Spatrick A[i] = i;
4933cab2bb3Spatrick EXPECT_DEATH(A[-1] = 0, expected_death);
4943cab2bb3Spatrick EXPECT_DEATH(A[-5] = 0, expected_death);
4953cab2bb3Spatrick EXPECT_DEATH(A[kSize] = 0, expected_death);
4963cab2bb3Spatrick EXPECT_DEATH(A[kSize + 1] = 0, expected_death);
4973cab2bb3Spatrick EXPECT_DEATH(A[kSize + 5] = 0, expected_death);
4983cab2bb3Spatrick if (kSize > 16)
4993cab2bb3Spatrick EXPECT_DEATH(A[kSize + 31] = 0, expected_death);
5003cab2bb3Spatrick }
5013cab2bb3Spatrick
TEST(AddressSanitizer,SimpleStackTest)5023cab2bb3Spatrick TEST(AddressSanitizer, SimpleStackTest) {
5033cab2bb3Spatrick SizedStackTest<1>();
5043cab2bb3Spatrick SizedStackTest<2>();
5053cab2bb3Spatrick SizedStackTest<3>();
5063cab2bb3Spatrick SizedStackTest<4>();
5073cab2bb3Spatrick SizedStackTest<5>();
5083cab2bb3Spatrick SizedStackTest<6>();
5093cab2bb3Spatrick SizedStackTest<7>();
5103cab2bb3Spatrick SizedStackTest<16>();
5113cab2bb3Spatrick SizedStackTest<25>();
5123cab2bb3Spatrick SizedStackTest<34>();
5133cab2bb3Spatrick SizedStackTest<43>();
5143cab2bb3Spatrick SizedStackTest<51>();
5153cab2bb3Spatrick SizedStackTest<62>();
5163cab2bb3Spatrick SizedStackTest<64>();
5173cab2bb3Spatrick SizedStackTest<128>();
5183cab2bb3Spatrick }
5193cab2bb3Spatrick
5203cab2bb3Spatrick #if !defined(_WIN32)
5213cab2bb3Spatrick // FIXME: It's a bit hard to write multi-line death test expectations
5223cab2bb3Spatrick // in a portable way. Anyways, this should just be turned into a lit test.
TEST(AddressSanitizer,ManyStackObjectsTest)5233cab2bb3Spatrick TEST(AddressSanitizer, ManyStackObjectsTest) {
5243cab2bb3Spatrick char XXX[10];
5253cab2bb3Spatrick char YYY[20];
5263cab2bb3Spatrick char ZZZ[30];
5273cab2bb3Spatrick Ident(XXX);
5283cab2bb3Spatrick Ident(YYY);
5293cab2bb3Spatrick EXPECT_DEATH(Ident(ZZZ)[-1] = 0, ASAN_PCRE_DOTALL "XXX.*YYY.*ZZZ");
5303cab2bb3Spatrick }
5313cab2bb3Spatrick #endif
5323cab2bb3Spatrick
5333cab2bb3Spatrick #if 0 // This test requires online symbolizer.
5343cab2bb3Spatrick // Moved to lit_tests/stack-oob-frames.cpp.
5353cab2bb3Spatrick // Reenable here once we have online symbolizer by default.
5363cab2bb3Spatrick NOINLINE static void Frame0(int frame, char *a, char *b, char *c) {
5373cab2bb3Spatrick char d[4] = {0};
5383cab2bb3Spatrick char *D = Ident(d);
5393cab2bb3Spatrick switch (frame) {
5403cab2bb3Spatrick case 3: a[5]++; break;
5413cab2bb3Spatrick case 2: b[5]++; break;
5423cab2bb3Spatrick case 1: c[5]++; break;
5433cab2bb3Spatrick case 0: D[5]++; break;
5443cab2bb3Spatrick }
5453cab2bb3Spatrick }
5463cab2bb3Spatrick NOINLINE static void Frame1(int frame, char *a, char *b) {
5473cab2bb3Spatrick char c[4] = {0}; Frame0(frame, a, b, c);
5483cab2bb3Spatrick break_optimization(0);
5493cab2bb3Spatrick }
5503cab2bb3Spatrick NOINLINE static void Frame2(int frame, char *a) {
5513cab2bb3Spatrick char b[4] = {0}; Frame1(frame, a, b);
5523cab2bb3Spatrick break_optimization(0);
5533cab2bb3Spatrick }
5543cab2bb3Spatrick NOINLINE static void Frame3(int frame) {
5553cab2bb3Spatrick char a[4] = {0}; Frame2(frame, a);
5563cab2bb3Spatrick break_optimization(0);
5573cab2bb3Spatrick }
5583cab2bb3Spatrick
5593cab2bb3Spatrick TEST(AddressSanitizer, GuiltyStackFrame0Test) {
5603cab2bb3Spatrick EXPECT_DEATH(Frame3(0), "located .*in frame <.*Frame0");
5613cab2bb3Spatrick }
5623cab2bb3Spatrick TEST(AddressSanitizer, GuiltyStackFrame1Test) {
5633cab2bb3Spatrick EXPECT_DEATH(Frame3(1), "located .*in frame <.*Frame1");
5643cab2bb3Spatrick }
5653cab2bb3Spatrick TEST(AddressSanitizer, GuiltyStackFrame2Test) {
5663cab2bb3Spatrick EXPECT_DEATH(Frame3(2), "located .*in frame <.*Frame2");
5673cab2bb3Spatrick }
5683cab2bb3Spatrick TEST(AddressSanitizer, GuiltyStackFrame3Test) {
5693cab2bb3Spatrick EXPECT_DEATH(Frame3(3), "located .*in frame <.*Frame3");
5703cab2bb3Spatrick }
5713cab2bb3Spatrick #endif
5723cab2bb3Spatrick
LongJmpFunc1(jmp_buf buf)5733cab2bb3Spatrick NOINLINE void LongJmpFunc1(jmp_buf buf) {
5743cab2bb3Spatrick // create three red zones for these two stack objects.
5753cab2bb3Spatrick int a;
5763cab2bb3Spatrick int b;
5773cab2bb3Spatrick
5783cab2bb3Spatrick int *A = Ident(&a);
5793cab2bb3Spatrick int *B = Ident(&b);
5803cab2bb3Spatrick *A = *B;
5813cab2bb3Spatrick longjmp(buf, 1);
5823cab2bb3Spatrick }
5833cab2bb3Spatrick
TouchStackFunc()5843cab2bb3Spatrick NOINLINE void TouchStackFunc() {
5853cab2bb3Spatrick int a[100]; // long array will intersect with redzones from LongJmpFunc1.
5863cab2bb3Spatrick int *A = Ident(a);
5873cab2bb3Spatrick for (int i = 0; i < 100; i++)
5883cab2bb3Spatrick A[i] = i*i;
5893cab2bb3Spatrick }
5903cab2bb3Spatrick
5913cab2bb3Spatrick // Test that we handle longjmp and do not report false positives on stack.
TEST(AddressSanitizer,LongJmpTest)5923cab2bb3Spatrick TEST(AddressSanitizer, LongJmpTest) {
5933cab2bb3Spatrick static jmp_buf buf;
5943cab2bb3Spatrick if (!setjmp(buf)) {
5953cab2bb3Spatrick LongJmpFunc1(buf);
5963cab2bb3Spatrick } else {
5973cab2bb3Spatrick TouchStackFunc();
5983cab2bb3Spatrick }
5993cab2bb3Spatrick }
6003cab2bb3Spatrick
6013cab2bb3Spatrick #if !defined(_WIN32) // Only basic longjmp is available on Windows.
UnderscopeLongJmpFunc1(jmp_buf buf)6023cab2bb3Spatrick NOINLINE void UnderscopeLongJmpFunc1(jmp_buf buf) {
6033cab2bb3Spatrick // create three red zones for these two stack objects.
6043cab2bb3Spatrick int a;
6053cab2bb3Spatrick int b;
6063cab2bb3Spatrick
6073cab2bb3Spatrick int *A = Ident(&a);
6083cab2bb3Spatrick int *B = Ident(&b);
6093cab2bb3Spatrick *A = *B;
6103cab2bb3Spatrick _longjmp(buf, 1);
6113cab2bb3Spatrick }
6123cab2bb3Spatrick
SigLongJmpFunc1(sigjmp_buf buf)6133cab2bb3Spatrick NOINLINE void SigLongJmpFunc1(sigjmp_buf buf) {
6143cab2bb3Spatrick // create three red zones for these two stack objects.
6153cab2bb3Spatrick int a;
6163cab2bb3Spatrick int b;
6173cab2bb3Spatrick
6183cab2bb3Spatrick int *A = Ident(&a);
6193cab2bb3Spatrick int *B = Ident(&b);
6203cab2bb3Spatrick *A = *B;
6213cab2bb3Spatrick siglongjmp(buf, 1);
6223cab2bb3Spatrick }
6233cab2bb3Spatrick
624d89ec533Spatrick #if !defined(__ANDROID__) && !defined(__arm__) && !defined(__aarch64__) && \
625d89ec533Spatrick !defined(__mips__) && !defined(__mips64) && !defined(__s390__) && \
626*810390e3Srobert !defined(__riscv) && !defined(__loongarch__)
BuiltinLongJmpFunc1(jmp_buf buf)6273cab2bb3Spatrick NOINLINE void BuiltinLongJmpFunc1(jmp_buf buf) {
6283cab2bb3Spatrick // create three red zones for these two stack objects.
6293cab2bb3Spatrick int a;
6303cab2bb3Spatrick int b;
6313cab2bb3Spatrick
6323cab2bb3Spatrick int *A = Ident(&a);
6333cab2bb3Spatrick int *B = Ident(&b);
6343cab2bb3Spatrick *A = *B;
6353cab2bb3Spatrick __builtin_longjmp((void**)buf, 1);
6363cab2bb3Spatrick }
6373cab2bb3Spatrick
6383cab2bb3Spatrick // Does not work on ARM:
6393cab2bb3Spatrick // https://github.com/google/sanitizers/issues/185
TEST(AddressSanitizer,BuiltinLongJmpTest)6403cab2bb3Spatrick TEST(AddressSanitizer, BuiltinLongJmpTest) {
6413cab2bb3Spatrick static jmp_buf buf;
6423cab2bb3Spatrick if (!__builtin_setjmp((void**)buf)) {
6433cab2bb3Spatrick BuiltinLongJmpFunc1(buf);
6443cab2bb3Spatrick } else {
6453cab2bb3Spatrick TouchStackFunc();
6463cab2bb3Spatrick }
6473cab2bb3Spatrick }
6483cab2bb3Spatrick #endif // !defined(__ANDROID__) && !defined(__arm__) &&
649*810390e3Srobert // !defined(__aarch64__) && !defined(__mips__) &&
650*810390e3Srobert // !defined(__mips64) && !defined(__s390__) &&
651*810390e3Srobert // !defined(__riscv) && !defined(__loongarch__)
6523cab2bb3Spatrick
TEST(AddressSanitizer,UnderscopeLongJmpTest)6533cab2bb3Spatrick TEST(AddressSanitizer, UnderscopeLongJmpTest) {
6543cab2bb3Spatrick static jmp_buf buf;
6553cab2bb3Spatrick if (!_setjmp(buf)) {
6563cab2bb3Spatrick UnderscopeLongJmpFunc1(buf);
6573cab2bb3Spatrick } else {
6583cab2bb3Spatrick TouchStackFunc();
6593cab2bb3Spatrick }
6603cab2bb3Spatrick }
6613cab2bb3Spatrick
TEST(AddressSanitizer,SigLongJmpTest)6623cab2bb3Spatrick TEST(AddressSanitizer, SigLongJmpTest) {
6633cab2bb3Spatrick static sigjmp_buf buf;
6643cab2bb3Spatrick if (!sigsetjmp(buf, 1)) {
6653cab2bb3Spatrick SigLongJmpFunc1(buf);
6663cab2bb3Spatrick } else {
6673cab2bb3Spatrick TouchStackFunc();
6683cab2bb3Spatrick }
6693cab2bb3Spatrick }
6703cab2bb3Spatrick #endif
6713cab2bb3Spatrick
6723cab2bb3Spatrick // FIXME: Why does clang-cl define __EXCEPTIONS?
6733cab2bb3Spatrick #if defined(__EXCEPTIONS) && !defined(_WIN32)
ThrowFunc()6743cab2bb3Spatrick NOINLINE void ThrowFunc() {
6753cab2bb3Spatrick // create three red zones for these two stack objects.
6763cab2bb3Spatrick int a;
6773cab2bb3Spatrick int b;
6783cab2bb3Spatrick
6793cab2bb3Spatrick int *A = Ident(&a);
6803cab2bb3Spatrick int *B = Ident(&b);
6813cab2bb3Spatrick *A = *B;
6823cab2bb3Spatrick ASAN_THROW(1);
6833cab2bb3Spatrick }
6843cab2bb3Spatrick
TEST(AddressSanitizer,CxxExceptionTest)6853cab2bb3Spatrick TEST(AddressSanitizer, CxxExceptionTest) {
6863cab2bb3Spatrick if (ASAN_UAR) return;
6873cab2bb3Spatrick // TODO(kcc): this test crashes on 32-bit for some reason...
6883cab2bb3Spatrick if (SANITIZER_WORDSIZE == 32) return;
6893cab2bb3Spatrick try {
6903cab2bb3Spatrick ThrowFunc();
6913cab2bb3Spatrick } catch(...) {}
6923cab2bb3Spatrick TouchStackFunc();
6933cab2bb3Spatrick }
6943cab2bb3Spatrick #endif
6953cab2bb3Spatrick
ThreadStackReuseFunc1(void * unused)6963cab2bb3Spatrick void *ThreadStackReuseFunc1(void *unused) {
6973cab2bb3Spatrick // create three red zones for these two stack objects.
6983cab2bb3Spatrick int a;
6993cab2bb3Spatrick int b;
7003cab2bb3Spatrick
7013cab2bb3Spatrick int *A = Ident(&a);
7023cab2bb3Spatrick int *B = Ident(&b);
7033cab2bb3Spatrick *A = *B;
7043cab2bb3Spatrick pthread_exit(0);
7053cab2bb3Spatrick return 0;
7063cab2bb3Spatrick }
7073cab2bb3Spatrick
ThreadStackReuseFunc2(void * unused)7083cab2bb3Spatrick void *ThreadStackReuseFunc2(void *unused) {
7093cab2bb3Spatrick TouchStackFunc();
7103cab2bb3Spatrick return 0;
7113cab2bb3Spatrick }
7123cab2bb3Spatrick
7133cab2bb3Spatrick #if !defined(__thumb__)
TEST(AddressSanitizer,ThreadStackReuseTest)7143cab2bb3Spatrick TEST(AddressSanitizer, ThreadStackReuseTest) {
7153cab2bb3Spatrick pthread_t t;
7163cab2bb3Spatrick PTHREAD_CREATE(&t, 0, ThreadStackReuseFunc1, 0);
7173cab2bb3Spatrick PTHREAD_JOIN(t, 0);
7183cab2bb3Spatrick PTHREAD_CREATE(&t, 0, ThreadStackReuseFunc2, 0);
7193cab2bb3Spatrick PTHREAD_JOIN(t, 0);
7203cab2bb3Spatrick }
7213cab2bb3Spatrick #endif
7223cab2bb3Spatrick
7233cab2bb3Spatrick #if defined(__SSE2__)
7243cab2bb3Spatrick #include <emmintrin.h>
TEST(AddressSanitizer,Store128Test)7253cab2bb3Spatrick TEST(AddressSanitizer, Store128Test) {
7263cab2bb3Spatrick char *a = Ident((char*)malloc(Ident(12)));
7273cab2bb3Spatrick char *p = a;
7283cab2bb3Spatrick if (((uintptr_t)a % 16) != 0)
7293cab2bb3Spatrick p = a + 8;
7303cab2bb3Spatrick assert(((uintptr_t)p % 16) == 0);
7313cab2bb3Spatrick __m128i value_wide = _mm_set1_epi16(0x1234);
7323cab2bb3Spatrick EXPECT_DEATH(_mm_store_si128((__m128i*)p, value_wide),
7333cab2bb3Spatrick "AddressSanitizer: heap-buffer-overflow");
7343cab2bb3Spatrick EXPECT_DEATH(_mm_store_si128((__m128i*)p, value_wide),
7353cab2bb3Spatrick "WRITE of size 16");
7363cab2bb3Spatrick EXPECT_DEATH(_mm_store_si128((__m128i*)p, value_wide),
737*810390e3Srobert "located 0 bytes after 12-byte");
7383cab2bb3Spatrick free(a);
7393cab2bb3Spatrick }
7403cab2bb3Spatrick #endif
7413cab2bb3Spatrick
7423cab2bb3Spatrick // FIXME: All tests that use this function should be turned into lit tests.
RightOOBErrorMessage(int oob_distance,bool is_write)7431f9cb04fSpatrick std::string RightOOBErrorMessage(int oob_distance, bool is_write) {
7443cab2bb3Spatrick assert(oob_distance >= 0);
7453cab2bb3Spatrick char expected_str[100];
7463cab2bb3Spatrick sprintf(expected_str, ASAN_PCRE_DOTALL
7473cab2bb3Spatrick #if !GTEST_USES_SIMPLE_RE
7483cab2bb3Spatrick "buffer-overflow.*%s.*"
7493cab2bb3Spatrick #endif
750*810390e3Srobert "located %d bytes after",
7513cab2bb3Spatrick #if !GTEST_USES_SIMPLE_RE
7523cab2bb3Spatrick is_write ? "WRITE" : "READ",
7533cab2bb3Spatrick #endif
7543cab2bb3Spatrick oob_distance);
7551f9cb04fSpatrick return std::string(expected_str);
7563cab2bb3Spatrick }
7573cab2bb3Spatrick
RightOOBWriteMessage(int oob_distance)7581f9cb04fSpatrick std::string RightOOBWriteMessage(int oob_distance) {
7593cab2bb3Spatrick return RightOOBErrorMessage(oob_distance, /*is_write*/true);
7603cab2bb3Spatrick }
7613cab2bb3Spatrick
RightOOBReadMessage(int oob_distance)7621f9cb04fSpatrick std::string RightOOBReadMessage(int oob_distance) {
7633cab2bb3Spatrick return RightOOBErrorMessage(oob_distance, /*is_write*/false);
7643cab2bb3Spatrick }
7653cab2bb3Spatrick
7663cab2bb3Spatrick // FIXME: All tests that use this function should be turned into lit tests.
LeftOOBErrorMessage(int oob_distance,bool is_write)7671f9cb04fSpatrick std::string LeftOOBErrorMessage(int oob_distance, bool is_write) {
7683cab2bb3Spatrick assert(oob_distance > 0);
7693cab2bb3Spatrick char expected_str[100];
7703cab2bb3Spatrick sprintf(expected_str,
7713cab2bb3Spatrick #if !GTEST_USES_SIMPLE_RE
7723cab2bb3Spatrick ASAN_PCRE_DOTALL "%s.*"
7733cab2bb3Spatrick #endif
774*810390e3Srobert "located %d bytes before",
7753cab2bb3Spatrick #if !GTEST_USES_SIMPLE_RE
7763cab2bb3Spatrick is_write ? "WRITE" : "READ",
7773cab2bb3Spatrick #endif
7783cab2bb3Spatrick oob_distance);
7791f9cb04fSpatrick return std::string(expected_str);
7803cab2bb3Spatrick }
7813cab2bb3Spatrick
LeftOOBWriteMessage(int oob_distance)7821f9cb04fSpatrick std::string LeftOOBWriteMessage(int oob_distance) {
7833cab2bb3Spatrick return LeftOOBErrorMessage(oob_distance, /*is_write*/true);
7843cab2bb3Spatrick }
7853cab2bb3Spatrick
LeftOOBReadMessage(int oob_distance)7861f9cb04fSpatrick std::string LeftOOBReadMessage(int oob_distance) {
7873cab2bb3Spatrick return LeftOOBErrorMessage(oob_distance, /*is_write*/false);
7883cab2bb3Spatrick }
7893cab2bb3Spatrick
LeftOOBAccessMessage(int oob_distance)7901f9cb04fSpatrick std::string LeftOOBAccessMessage(int oob_distance) {
7913cab2bb3Spatrick assert(oob_distance > 0);
7923cab2bb3Spatrick char expected_str[100];
793*810390e3Srobert sprintf(expected_str, "located %d bytes before", oob_distance);
7941f9cb04fSpatrick return std::string(expected_str);
7953cab2bb3Spatrick }
7963cab2bb3Spatrick
MallocAndMemsetString(size_t size,char ch)7973cab2bb3Spatrick char* MallocAndMemsetString(size_t size, char ch) {
7983cab2bb3Spatrick char *s = Ident((char*)malloc(size));
7993cab2bb3Spatrick memset(s, ch, size);
8003cab2bb3Spatrick return s;
8013cab2bb3Spatrick }
8023cab2bb3Spatrick
MallocAndMemsetString(size_t size)8033cab2bb3Spatrick char* MallocAndMemsetString(size_t size) {
8043cab2bb3Spatrick return MallocAndMemsetString(size, 'z');
8053cab2bb3Spatrick }
8063cab2bb3Spatrick
807d89ec533Spatrick #if SANITIZER_GLIBC
8083cab2bb3Spatrick #define READ_TEST(READ_N_BYTES) \
8093cab2bb3Spatrick char *x = new char[10]; \
8103cab2bb3Spatrick int fd = open("/proc/self/stat", O_RDONLY); \
8113cab2bb3Spatrick ASSERT_GT(fd, 0); \
8123cab2bb3Spatrick EXPECT_DEATH(READ_N_BYTES, \
8133cab2bb3Spatrick ASAN_PCRE_DOTALL \
8143cab2bb3Spatrick "AddressSanitizer: heap-buffer-overflow" \
815*810390e3Srobert ".* is located 0 bytes after 10-byte region"); \
8163cab2bb3Spatrick close(fd); \
8173cab2bb3Spatrick delete [] x; \
8183cab2bb3Spatrick
TEST(AddressSanitizer,pread)8193cab2bb3Spatrick TEST(AddressSanitizer, pread) {
8203cab2bb3Spatrick READ_TEST(pread(fd, x, 15, 0));
8213cab2bb3Spatrick }
8223cab2bb3Spatrick
TEST(AddressSanitizer,pread64)8233cab2bb3Spatrick TEST(AddressSanitizer, pread64) {
8243cab2bb3Spatrick READ_TEST(pread64(fd, x, 15, 0));
8253cab2bb3Spatrick }
8263cab2bb3Spatrick
TEST(AddressSanitizer,read)8273cab2bb3Spatrick TEST(AddressSanitizer, read) {
8283cab2bb3Spatrick READ_TEST(read(fd, x, 15));
8293cab2bb3Spatrick }
830d89ec533Spatrick #endif // SANITIZER_GLIBC
8313cab2bb3Spatrick
8323cab2bb3Spatrick // This test case fails
8333cab2bb3Spatrick // Clang optimizes memcpy/memset calls which lead to unaligned access
TEST(AddressSanitizer,DISABLED_MemIntrinsicUnalignedAccessTest)8343cab2bb3Spatrick TEST(AddressSanitizer, DISABLED_MemIntrinsicUnalignedAccessTest) {
8353cab2bb3Spatrick int size = Ident(4096);
8363cab2bb3Spatrick char *s = Ident((char*)malloc(size));
8373cab2bb3Spatrick EXPECT_DEATH(memset(s + size - 1, 0, 2), RightOOBWriteMessage(0));
8383cab2bb3Spatrick free(s);
8393cab2bb3Spatrick }
8403cab2bb3Spatrick
LargeFunction(bool do_bad_access)8413cab2bb3Spatrick NOINLINE static int LargeFunction(bool do_bad_access) {
8423cab2bb3Spatrick int *x = new int[100];
8433cab2bb3Spatrick x[0]++;
8443cab2bb3Spatrick x[1]++;
8453cab2bb3Spatrick x[2]++;
8463cab2bb3Spatrick x[3]++;
8473cab2bb3Spatrick x[4]++;
8483cab2bb3Spatrick x[5]++;
8493cab2bb3Spatrick x[6]++;
8503cab2bb3Spatrick x[7]++;
8513cab2bb3Spatrick x[8]++;
8523cab2bb3Spatrick x[9]++;
8533cab2bb3Spatrick
8543cab2bb3Spatrick x[do_bad_access ? 100 : 0]++; int res = __LINE__;
8553cab2bb3Spatrick
8563cab2bb3Spatrick x[10]++;
8573cab2bb3Spatrick x[11]++;
8583cab2bb3Spatrick x[12]++;
8593cab2bb3Spatrick x[13]++;
8603cab2bb3Spatrick x[14]++;
8613cab2bb3Spatrick x[15]++;
8623cab2bb3Spatrick x[16]++;
8633cab2bb3Spatrick x[17]++;
8643cab2bb3Spatrick x[18]++;
8653cab2bb3Spatrick x[19]++;
8663cab2bb3Spatrick
8673cab2bb3Spatrick delete[] x;
8683cab2bb3Spatrick return res;
8693cab2bb3Spatrick }
8703cab2bb3Spatrick
8713cab2bb3Spatrick // Test the we have correct debug info for the failing instruction.
8723cab2bb3Spatrick // This test requires the in-process symbolizer to be enabled by default.
TEST(AddressSanitizer,DISABLED_LargeFunctionSymbolizeTest)8733cab2bb3Spatrick TEST(AddressSanitizer, DISABLED_LargeFunctionSymbolizeTest) {
8743cab2bb3Spatrick int failing_line = LargeFunction(false);
8753cab2bb3Spatrick char expected_warning[128];
8763cab2bb3Spatrick sprintf(expected_warning, "LargeFunction.*asan_test.*:%d", failing_line);
8773cab2bb3Spatrick EXPECT_DEATH(LargeFunction(true), expected_warning);
8783cab2bb3Spatrick }
8793cab2bb3Spatrick
8803cab2bb3Spatrick // Check that we unwind and symbolize correctly.
TEST(AddressSanitizer,DISABLED_MallocFreeUnwindAndSymbolizeTest)8813cab2bb3Spatrick TEST(AddressSanitizer, DISABLED_MallocFreeUnwindAndSymbolizeTest) {
8823cab2bb3Spatrick int *a = (int*)malloc_aaa(sizeof(int));
8833cab2bb3Spatrick *a = 1;
8843cab2bb3Spatrick free_aaa(a);
8853cab2bb3Spatrick EXPECT_DEATH(*a = 1, "free_ccc.*free_bbb.*free_aaa.*"
8863cab2bb3Spatrick "malloc_fff.*malloc_eee.*malloc_ddd");
8873cab2bb3Spatrick }
8883cab2bb3Spatrick
TryToSetThreadName(const char * name)8893cab2bb3Spatrick static bool TryToSetThreadName(const char *name) {
8903cab2bb3Spatrick #if defined(__linux__) && defined(PR_SET_NAME)
8913cab2bb3Spatrick return 0 == prctl(PR_SET_NAME, (unsigned long)name, 0, 0, 0);
8923cab2bb3Spatrick #else
8933cab2bb3Spatrick return false;
8943cab2bb3Spatrick #endif
8953cab2bb3Spatrick }
8963cab2bb3Spatrick
ThreadedTestAlloc(void * a)8973cab2bb3Spatrick void *ThreadedTestAlloc(void *a) {
8983cab2bb3Spatrick EXPECT_EQ(true, TryToSetThreadName("AllocThr"));
8993cab2bb3Spatrick int **p = (int**)a;
9003cab2bb3Spatrick *p = new int;
9013cab2bb3Spatrick return 0;
9023cab2bb3Spatrick }
9033cab2bb3Spatrick
ThreadedTestFree(void * a)9043cab2bb3Spatrick void *ThreadedTestFree(void *a) {
9053cab2bb3Spatrick EXPECT_EQ(true, TryToSetThreadName("FreeThr"));
9063cab2bb3Spatrick int **p = (int**)a;
9073cab2bb3Spatrick delete *p;
9083cab2bb3Spatrick return 0;
9093cab2bb3Spatrick }
9103cab2bb3Spatrick
ThreadedTestUse(void * a)9113cab2bb3Spatrick void *ThreadedTestUse(void *a) {
9123cab2bb3Spatrick EXPECT_EQ(true, TryToSetThreadName("UseThr"));
9133cab2bb3Spatrick int **p = (int**)a;
9143cab2bb3Spatrick **p = 1;
9153cab2bb3Spatrick return 0;
9163cab2bb3Spatrick }
9173cab2bb3Spatrick
ThreadedTestSpawn()9183cab2bb3Spatrick void ThreadedTestSpawn() {
9193cab2bb3Spatrick pthread_t t;
9203cab2bb3Spatrick int *x;
9213cab2bb3Spatrick PTHREAD_CREATE(&t, 0, ThreadedTestAlloc, &x);
9223cab2bb3Spatrick PTHREAD_JOIN(t, 0);
9233cab2bb3Spatrick PTHREAD_CREATE(&t, 0, ThreadedTestFree, &x);
9243cab2bb3Spatrick PTHREAD_JOIN(t, 0);
9253cab2bb3Spatrick PTHREAD_CREATE(&t, 0, ThreadedTestUse, &x);
9263cab2bb3Spatrick PTHREAD_JOIN(t, 0);
9273cab2bb3Spatrick }
9283cab2bb3Spatrick
9293cab2bb3Spatrick #if !defined(_WIN32) // FIXME: This should be a lit test.
TEST(AddressSanitizer,ThreadedTest)9303cab2bb3Spatrick TEST(AddressSanitizer, ThreadedTest) {
9313cab2bb3Spatrick EXPECT_DEATH(ThreadedTestSpawn(),
9323cab2bb3Spatrick ASAN_PCRE_DOTALL
9333cab2bb3Spatrick "Thread T.*created"
9343cab2bb3Spatrick ".*Thread T.*created"
9353cab2bb3Spatrick ".*Thread T.*created");
9363cab2bb3Spatrick }
9373cab2bb3Spatrick #endif
9383cab2bb3Spatrick
ThreadedTestFunc(void * unused)9393cab2bb3Spatrick void *ThreadedTestFunc(void *unused) {
9403cab2bb3Spatrick // Check if prctl(PR_SET_NAME) is supported. Return if not.
9413cab2bb3Spatrick if (!TryToSetThreadName("TestFunc"))
9423cab2bb3Spatrick return 0;
9433cab2bb3Spatrick EXPECT_DEATH(ThreadedTestSpawn(),
9443cab2bb3Spatrick ASAN_PCRE_DOTALL
9453cab2bb3Spatrick "WRITE .*thread T. .UseThr."
9463cab2bb3Spatrick ".*freed by thread T. .FreeThr. here:"
9473cab2bb3Spatrick ".*previously allocated by thread T. .AllocThr. here:"
9483cab2bb3Spatrick ".*Thread T. .UseThr. created by T.*TestFunc"
9493cab2bb3Spatrick ".*Thread T. .FreeThr. created by T"
9503cab2bb3Spatrick ".*Thread T. .AllocThr. created by T"
9513cab2bb3Spatrick "");
9523cab2bb3Spatrick return 0;
9533cab2bb3Spatrick }
9543cab2bb3Spatrick
TEST(AddressSanitizer,ThreadNamesTest)9553cab2bb3Spatrick TEST(AddressSanitizer, ThreadNamesTest) {
9563cab2bb3Spatrick // Run ThreadedTestFunc in a separate thread because it tries to set a
9573cab2bb3Spatrick // thread name and we don't want to change the main thread's name.
9583cab2bb3Spatrick pthread_t t;
9593cab2bb3Spatrick PTHREAD_CREATE(&t, 0, ThreadedTestFunc, 0);
9603cab2bb3Spatrick PTHREAD_JOIN(t, 0);
9613cab2bb3Spatrick }
9623cab2bb3Spatrick
9633cab2bb3Spatrick #if ASAN_NEEDS_SEGV
TEST(AddressSanitizer,ShadowGapTest)9643cab2bb3Spatrick TEST(AddressSanitizer, ShadowGapTest) {
9653cab2bb3Spatrick #if SANITIZER_WORDSIZE == 32
9663cab2bb3Spatrick char *addr = (char*)0x23000000;
9673cab2bb3Spatrick #else
9683cab2bb3Spatrick # if defined(__powerpc64__)
9693cab2bb3Spatrick char *addr = (char*)0x024000800000;
9703cab2bb3Spatrick # elif defined(__s390x__)
9713cab2bb3Spatrick char *addr = (char*)0x11000000000000;
9723cab2bb3Spatrick # else
9733cab2bb3Spatrick char *addr = (char*)0x0000100000080000;
9743cab2bb3Spatrick # endif
9753cab2bb3Spatrick #endif
9763cab2bb3Spatrick EXPECT_DEATH(*addr = 1, "AddressSanitizer: (SEGV|BUS) on unknown");
9773cab2bb3Spatrick }
9783cab2bb3Spatrick #endif // ASAN_NEEDS_SEGV
9793cab2bb3Spatrick
9803cab2bb3Spatrick extern "C" {
UseThenFreeThenUse()9813cab2bb3Spatrick NOINLINE static void UseThenFreeThenUse() {
9823cab2bb3Spatrick char *x = Ident((char*)malloc(8));
9833cab2bb3Spatrick *x = 1;
9843cab2bb3Spatrick free_aaa(x);
9853cab2bb3Spatrick *x = 2;
9863cab2bb3Spatrick }
9873cab2bb3Spatrick }
9883cab2bb3Spatrick
TEST(AddressSanitizer,UseThenFreeThenUseTest)9893cab2bb3Spatrick TEST(AddressSanitizer, UseThenFreeThenUseTest) {
9903cab2bb3Spatrick EXPECT_DEATH(UseThenFreeThenUse(), "freed by thread");
9913cab2bb3Spatrick }
9923cab2bb3Spatrick
TEST(AddressSanitizer,StrDupTest)9933cab2bb3Spatrick TEST(AddressSanitizer, StrDupTest) {
9943cab2bb3Spatrick free(strdup(Ident("123")));
9953cab2bb3Spatrick }
9963cab2bb3Spatrick
9973cab2bb3Spatrick // Currently we create and poison redzone at right of global variables.
9983cab2bb3Spatrick static char static110[110];
9993cab2bb3Spatrick const char ConstGlob[7] = {1, 2, 3, 4, 5, 6, 7};
10003cab2bb3Spatrick static const char StaticConstGlob[3] = {9, 8, 7};
10013cab2bb3Spatrick
TEST(AddressSanitizer,GlobalTest)10023cab2bb3Spatrick TEST(AddressSanitizer, GlobalTest) {
10033cab2bb3Spatrick static char func_static15[15];
10043cab2bb3Spatrick
10053cab2bb3Spatrick static char fs1[10];
10063cab2bb3Spatrick static char fs2[10];
10073cab2bb3Spatrick static char fs3[10];
10083cab2bb3Spatrick
10093cab2bb3Spatrick glob5[Ident(0)] = 0;
10103cab2bb3Spatrick glob5[Ident(1)] = 0;
10113cab2bb3Spatrick glob5[Ident(2)] = 0;
10123cab2bb3Spatrick glob5[Ident(3)] = 0;
10133cab2bb3Spatrick glob5[Ident(4)] = 0;
10143cab2bb3Spatrick
10153cab2bb3Spatrick EXPECT_DEATH(glob5[Ident(5)] = 0,
1016*810390e3Srobert "0 bytes after global variable.*glob5.* size 5");
10173cab2bb3Spatrick EXPECT_DEATH(glob5[Ident(5+6)] = 0,
1018*810390e3Srobert "6 bytes after global variable.*glob5.* size 5");
10193cab2bb3Spatrick Ident(static110); // avoid optimizations
10203cab2bb3Spatrick static110[Ident(0)] = 0;
10213cab2bb3Spatrick static110[Ident(109)] = 0;
10223cab2bb3Spatrick EXPECT_DEATH(static110[Ident(110)] = 0,
1023*810390e3Srobert "0 bytes after global variable");
10243cab2bb3Spatrick EXPECT_DEATH(static110[Ident(110+7)] = 0,
1025*810390e3Srobert "7 bytes after global variable");
10263cab2bb3Spatrick
10273cab2bb3Spatrick Ident(func_static15); // avoid optimizations
10283cab2bb3Spatrick func_static15[Ident(0)] = 0;
10293cab2bb3Spatrick EXPECT_DEATH(func_static15[Ident(15)] = 0,
1030*810390e3Srobert "0 bytes after global variable");
10313cab2bb3Spatrick EXPECT_DEATH(func_static15[Ident(15 + 9)] = 0,
1032*810390e3Srobert "9 bytes after global variable");
10333cab2bb3Spatrick
10343cab2bb3Spatrick Ident(fs1);
10353cab2bb3Spatrick Ident(fs2);
10363cab2bb3Spatrick Ident(fs3);
10373cab2bb3Spatrick
10383cab2bb3Spatrick // We don't create left redzones, so this is not 100% guaranteed to fail.
10393cab2bb3Spatrick // But most likely will.
1040*810390e3Srobert EXPECT_DEATH(fs2[Ident(-1)] = 0, "is located.* global variable");
10413cab2bb3Spatrick
10423cab2bb3Spatrick EXPECT_DEATH(Ident(Ident(ConstGlob)[8]),
1043*810390e3Srobert "is located 1 bytes after .*ConstGlob");
10443cab2bb3Spatrick EXPECT_DEATH(Ident(Ident(StaticConstGlob)[5]),
1045*810390e3Srobert "is located 2 bytes after .*StaticConstGlob");
10463cab2bb3Spatrick
10473cab2bb3Spatrick // call stuff from another file.
10483cab2bb3Spatrick GlobalsTest(0);
10493cab2bb3Spatrick }
10503cab2bb3Spatrick
TEST(AddressSanitizer,GlobalStringConstTest)10513cab2bb3Spatrick TEST(AddressSanitizer, GlobalStringConstTest) {
10523cab2bb3Spatrick static const char *zoo = "FOOBAR123";
10533cab2bb3Spatrick const char *p = Ident(zoo);
10543cab2bb3Spatrick EXPECT_DEATH(Ident(p[15]), "is ascii string 'FOOBAR123'");
10553cab2bb3Spatrick }
10563cab2bb3Spatrick
TEST(AddressSanitizer,FileNameInGlobalReportTest)10573cab2bb3Spatrick TEST(AddressSanitizer, FileNameInGlobalReportTest) {
10583cab2bb3Spatrick static char zoo[10];
10593cab2bb3Spatrick const char *p = Ident(zoo);
10603cab2bb3Spatrick // The file name should be present in the report.
10613cab2bb3Spatrick EXPECT_DEATH(Ident(p[15]), "zoo.*asan_test.");
10623cab2bb3Spatrick }
10633cab2bb3Spatrick
ReturnsPointerToALocalObject()10643cab2bb3Spatrick int *ReturnsPointerToALocalObject() {
10653cab2bb3Spatrick int a = 0;
10663cab2bb3Spatrick return Ident(&a);
10673cab2bb3Spatrick }
10683cab2bb3Spatrick
10693cab2bb3Spatrick #if ASAN_UAR == 1
TEST(AddressSanitizer,LocalReferenceReturnTest)10703cab2bb3Spatrick TEST(AddressSanitizer, LocalReferenceReturnTest) {
10713cab2bb3Spatrick int *(*f)() = Ident(ReturnsPointerToALocalObject);
10723cab2bb3Spatrick int *p = f();
10733cab2bb3Spatrick // Call 'f' a few more times, 'p' should still be poisoned.
10743cab2bb3Spatrick for (int i = 0; i < 32; i++)
10753cab2bb3Spatrick f();
10763cab2bb3Spatrick EXPECT_DEATH(*p = 1, "AddressSanitizer: stack-use-after-return");
10773cab2bb3Spatrick EXPECT_DEATH(*p = 1, "is located.*in frame .*ReturnsPointerToALocal");
10783cab2bb3Spatrick }
10793cab2bb3Spatrick #endif
10803cab2bb3Spatrick
10813cab2bb3Spatrick template <int kSize>
FuncWithStack()10823cab2bb3Spatrick NOINLINE static void FuncWithStack() {
10833cab2bb3Spatrick char x[kSize];
10843cab2bb3Spatrick Ident(x)[0] = 0;
10853cab2bb3Spatrick Ident(x)[kSize-1] = 0;
10863cab2bb3Spatrick }
10873cab2bb3Spatrick
LotsOfStackReuse()10883cab2bb3Spatrick static void LotsOfStackReuse() {
10893cab2bb3Spatrick int LargeStack[10000];
10903cab2bb3Spatrick Ident(LargeStack)[0] = 0;
10913cab2bb3Spatrick for (int i = 0; i < 10000; i++) {
10923cab2bb3Spatrick FuncWithStack<128 * 1>();
10933cab2bb3Spatrick FuncWithStack<128 * 2>();
10943cab2bb3Spatrick FuncWithStack<128 * 4>();
10953cab2bb3Spatrick FuncWithStack<128 * 8>();
10963cab2bb3Spatrick FuncWithStack<128 * 16>();
10973cab2bb3Spatrick FuncWithStack<128 * 32>();
10983cab2bb3Spatrick FuncWithStack<128 * 64>();
10993cab2bb3Spatrick FuncWithStack<128 * 128>();
11003cab2bb3Spatrick FuncWithStack<128 * 256>();
11013cab2bb3Spatrick FuncWithStack<128 * 512>();
11023cab2bb3Spatrick Ident(LargeStack)[0] = 0;
11033cab2bb3Spatrick }
11043cab2bb3Spatrick }
11053cab2bb3Spatrick
TEST(AddressSanitizer,StressStackReuseTest)11063cab2bb3Spatrick TEST(AddressSanitizer, StressStackReuseTest) {
11073cab2bb3Spatrick LotsOfStackReuse();
11083cab2bb3Spatrick }
11093cab2bb3Spatrick
TEST(AddressSanitizer,ThreadedStressStackReuseTest)11103cab2bb3Spatrick TEST(AddressSanitizer, ThreadedStressStackReuseTest) {
11113cab2bb3Spatrick const int kNumThreads = 20;
11123cab2bb3Spatrick pthread_t t[kNumThreads];
11133cab2bb3Spatrick for (int i = 0; i < kNumThreads; i++) {
11143cab2bb3Spatrick PTHREAD_CREATE(&t[i], 0, (void* (*)(void *x))LotsOfStackReuse, 0);
11153cab2bb3Spatrick }
11163cab2bb3Spatrick for (int i = 0; i < kNumThreads; i++) {
11173cab2bb3Spatrick PTHREAD_JOIN(t[i], 0);
11183cab2bb3Spatrick }
11193cab2bb3Spatrick }
11203cab2bb3Spatrick
11213cab2bb3Spatrick // pthread_exit tries to perform unwinding stuff that leads to dlopen'ing
11223cab2bb3Spatrick // libgcc_s.so. dlopen in its turn calls malloc to store "libgcc_s.so" string
11233cab2bb3Spatrick // that confuses LSan on Thumb because it fails to understand that this
11243cab2bb3Spatrick // allocation happens in dynamic linker and should be ignored.
11253cab2bb3Spatrick #if !defined(__thumb__)
PthreadExit(void * a)11263cab2bb3Spatrick static void *PthreadExit(void *a) {
11273cab2bb3Spatrick pthread_exit(0);
11283cab2bb3Spatrick return 0;
11293cab2bb3Spatrick }
11303cab2bb3Spatrick
TEST(AddressSanitizer,PthreadExitTest)11313cab2bb3Spatrick TEST(AddressSanitizer, PthreadExitTest) {
11323cab2bb3Spatrick pthread_t t;
11333cab2bb3Spatrick for (int i = 0; i < 1000; i++) {
11343cab2bb3Spatrick PTHREAD_CREATE(&t, 0, PthreadExit, 0);
11353cab2bb3Spatrick PTHREAD_JOIN(t, 0);
11363cab2bb3Spatrick }
11373cab2bb3Spatrick }
11383cab2bb3Spatrick #endif
11393cab2bb3Spatrick
11403cab2bb3Spatrick // FIXME: Why does clang-cl define __EXCEPTIONS?
11413cab2bb3Spatrick #if defined(__EXCEPTIONS) && !defined(_WIN32)
StackReuseAndException()11423cab2bb3Spatrick NOINLINE static void StackReuseAndException() {
11433cab2bb3Spatrick int large_stack[1000];
11443cab2bb3Spatrick Ident(large_stack);
11453cab2bb3Spatrick ASAN_THROW(1);
11463cab2bb3Spatrick }
11473cab2bb3Spatrick
11483cab2bb3Spatrick // TODO(kcc): support exceptions with use-after-return.
TEST(AddressSanitizer,DISABLED_StressStackReuseAndExceptionsTest)11493cab2bb3Spatrick TEST(AddressSanitizer, DISABLED_StressStackReuseAndExceptionsTest) {
11503cab2bb3Spatrick for (int i = 0; i < 10000; i++) {
11513cab2bb3Spatrick try {
11523cab2bb3Spatrick StackReuseAndException();
11533cab2bb3Spatrick } catch(...) {
11543cab2bb3Spatrick }
11553cab2bb3Spatrick }
11563cab2bb3Spatrick }
11573cab2bb3Spatrick #endif
11583cab2bb3Spatrick
11593cab2bb3Spatrick #if !defined(_WIN32)
TEST(AddressSanitizer,MlockTest)11603cab2bb3Spatrick TEST(AddressSanitizer, MlockTest) {
11611f9cb04fSpatrick #if !defined(__ANDROID__) || __ANDROID_API__ >= 17
11623cab2bb3Spatrick EXPECT_EQ(0, mlockall(MCL_CURRENT));
11631f9cb04fSpatrick #endif
11643cab2bb3Spatrick EXPECT_EQ(0, mlock((void*)0x12345, 0x5678));
11651f9cb04fSpatrick #if !defined(__ANDROID__) || __ANDROID_API__ >= 17
11663cab2bb3Spatrick EXPECT_EQ(0, munlockall());
11671f9cb04fSpatrick #endif
11683cab2bb3Spatrick EXPECT_EQ(0, munlock((void*)0x987, 0x654));
11693cab2bb3Spatrick }
11703cab2bb3Spatrick #endif
11713cab2bb3Spatrick
11723cab2bb3Spatrick struct LargeStruct {
11733cab2bb3Spatrick int foo[100];
11743cab2bb3Spatrick };
11753cab2bb3Spatrick
11763cab2bb3Spatrick // Test for bug http://llvm.org/bugs/show_bug.cgi?id=11763.
11773cab2bb3Spatrick // Struct copy should not cause asan warning even if lhs == rhs.
TEST(AddressSanitizer,LargeStructCopyTest)11783cab2bb3Spatrick TEST(AddressSanitizer, LargeStructCopyTest) {
11793cab2bb3Spatrick LargeStruct a;
11803cab2bb3Spatrick *Ident(&a) = *Ident(&a);
11813cab2bb3Spatrick }
11823cab2bb3Spatrick
11833cab2bb3Spatrick ATTRIBUTE_NO_SANITIZE_ADDRESS
NoSanitizeAddress()11843cab2bb3Spatrick static void NoSanitizeAddress() {
11853cab2bb3Spatrick char *foo = new char[10];
11863cab2bb3Spatrick Ident(foo)[10] = 0;
11873cab2bb3Spatrick delete [] foo;
11883cab2bb3Spatrick }
11893cab2bb3Spatrick
TEST(AddressSanitizer,AttributeNoSanitizeAddressTest)11903cab2bb3Spatrick TEST(AddressSanitizer, AttributeNoSanitizeAddressTest) {
11913cab2bb3Spatrick Ident(NoSanitizeAddress)();
11923cab2bb3Spatrick }
11933cab2bb3Spatrick
11943cab2bb3Spatrick // The new/delete/etc mismatch checks don't work on Android,
11953cab2bb3Spatrick // as calls to new/delete go through malloc/free.
11963cab2bb3Spatrick // OS X support is tracked here:
11973cab2bb3Spatrick // https://github.com/google/sanitizers/issues/131
11983cab2bb3Spatrick // Windows support is tracked here:
11993cab2bb3Spatrick // https://github.com/google/sanitizers/issues/309
12003cab2bb3Spatrick #if !defined(__ANDROID__) && \
12013cab2bb3Spatrick !defined(__APPLE__) && \
12023cab2bb3Spatrick !defined(_WIN32)
MismatchStr(const std::string & str)12031f9cb04fSpatrick static std::string MismatchStr(const std::string &str) {
12041f9cb04fSpatrick return std::string("AddressSanitizer: alloc-dealloc-mismatch \\(") + str;
12053cab2bb3Spatrick }
12063cab2bb3Spatrick
MismatchOrNewDeleteTypeStr(const std::string & mismatch_str)12071f9cb04fSpatrick static std::string MismatchOrNewDeleteTypeStr(const std::string &mismatch_str) {
12083cab2bb3Spatrick return "(" + MismatchStr(mismatch_str) +
12093cab2bb3Spatrick ")|(AddressSanitizer: new-delete-type-mismatch)";
12103cab2bb3Spatrick }
12113cab2bb3Spatrick
TEST(AddressSanitizer,AllocDeallocMismatch)12123cab2bb3Spatrick TEST(AddressSanitizer, AllocDeallocMismatch) {
12133cab2bb3Spatrick EXPECT_DEATH(free(Ident(new int)),
12143cab2bb3Spatrick MismatchStr("operator new vs free"));
12153cab2bb3Spatrick EXPECT_DEATH(free(Ident(new int[2])),
12163cab2bb3Spatrick MismatchStr("operator new \\[\\] vs free"));
12173cab2bb3Spatrick EXPECT_DEATH(
12183cab2bb3Spatrick delete (Ident(new int[2])),
12193cab2bb3Spatrick MismatchOrNewDeleteTypeStr("operator new \\[\\] vs operator delete"));
12203cab2bb3Spatrick EXPECT_DEATH(delete (Ident((int *)malloc(2 * sizeof(int)))),
12213cab2bb3Spatrick MismatchOrNewDeleteTypeStr("malloc vs operator delete"));
12223cab2bb3Spatrick EXPECT_DEATH(delete [] (Ident(new int)),
12233cab2bb3Spatrick MismatchStr("operator new vs operator delete \\[\\]"));
12243cab2bb3Spatrick EXPECT_DEATH(delete [] (Ident((int*)malloc(2 * sizeof(int)))),
12253cab2bb3Spatrick MismatchStr("malloc vs operator delete \\[\\]"));
12263cab2bb3Spatrick }
12273cab2bb3Spatrick #endif
12283cab2bb3Spatrick
12293cab2bb3Spatrick // ------------------ demo tests; run each one-by-one -------------
12303cab2bb3Spatrick // e.g. --gtest_filter=*DemoOOBLeftHigh --gtest_also_run_disabled_tests
TEST(AddressSanitizer,DISABLED_DemoThreadedTest)12313cab2bb3Spatrick TEST(AddressSanitizer, DISABLED_DemoThreadedTest) {
12323cab2bb3Spatrick ThreadedTestSpawn();
12333cab2bb3Spatrick }
12343cab2bb3Spatrick
SimpleBugOnSTack(void * x=0)12353cab2bb3Spatrick void *SimpleBugOnSTack(void *x = 0) {
12363cab2bb3Spatrick char a[20];
12373cab2bb3Spatrick Ident(a)[20] = 0;
12383cab2bb3Spatrick return 0;
12393cab2bb3Spatrick }
12403cab2bb3Spatrick
TEST(AddressSanitizer,DISABLED_DemoStackTest)12413cab2bb3Spatrick TEST(AddressSanitizer, DISABLED_DemoStackTest) {
12423cab2bb3Spatrick SimpleBugOnSTack();
12433cab2bb3Spatrick }
12443cab2bb3Spatrick
TEST(AddressSanitizer,DISABLED_DemoThreadStackTest)12453cab2bb3Spatrick TEST(AddressSanitizer, DISABLED_DemoThreadStackTest) {
12463cab2bb3Spatrick pthread_t t;
12473cab2bb3Spatrick PTHREAD_CREATE(&t, 0, SimpleBugOnSTack, 0);
12483cab2bb3Spatrick PTHREAD_JOIN(t, 0);
12493cab2bb3Spatrick }
12503cab2bb3Spatrick
TEST(AddressSanitizer,DISABLED_DemoUAFLowIn)12513cab2bb3Spatrick TEST(AddressSanitizer, DISABLED_DemoUAFLowIn) {
12523cab2bb3Spatrick uaf_test<U1>(10, 0);
12533cab2bb3Spatrick }
TEST(AddressSanitizer,DISABLED_DemoUAFLowLeft)12543cab2bb3Spatrick TEST(AddressSanitizer, DISABLED_DemoUAFLowLeft) {
12553cab2bb3Spatrick uaf_test<U1>(10, -2);
12563cab2bb3Spatrick }
TEST(AddressSanitizer,DISABLED_DemoUAFLowRight)12573cab2bb3Spatrick TEST(AddressSanitizer, DISABLED_DemoUAFLowRight) {
12583cab2bb3Spatrick uaf_test<U1>(10, 10);
12593cab2bb3Spatrick }
12603cab2bb3Spatrick
TEST(AddressSanitizer,DISABLED_DemoUAFHigh)12613cab2bb3Spatrick TEST(AddressSanitizer, DISABLED_DemoUAFHigh) {
12623cab2bb3Spatrick uaf_test<U1>(kLargeMalloc, 0);
12633cab2bb3Spatrick }
12643cab2bb3Spatrick
TEST(AddressSanitizer,DISABLED_DemoOOM)12653cab2bb3Spatrick TEST(AddressSanitizer, DISABLED_DemoOOM) {
12663cab2bb3Spatrick size_t size = SANITIZER_WORDSIZE == 64 ? (size_t)(1ULL << 40) : (0xf0000000);
12673cab2bb3Spatrick printf("%p\n", malloc(size));
12683cab2bb3Spatrick }
12693cab2bb3Spatrick
TEST(AddressSanitizer,DISABLED_DemoDoubleFreeTest)12703cab2bb3Spatrick TEST(AddressSanitizer, DISABLED_DemoDoubleFreeTest) {
12713cab2bb3Spatrick DoubleFree();
12723cab2bb3Spatrick }
12733cab2bb3Spatrick
TEST(AddressSanitizer,DISABLED_DemoNullDerefTest)12743cab2bb3Spatrick TEST(AddressSanitizer, DISABLED_DemoNullDerefTest) {
12753cab2bb3Spatrick int *a = 0;
12763cab2bb3Spatrick Ident(a)[10] = 0;
12773cab2bb3Spatrick }
12783cab2bb3Spatrick
TEST(AddressSanitizer,DISABLED_DemoFunctionStaticTest)12793cab2bb3Spatrick TEST(AddressSanitizer, DISABLED_DemoFunctionStaticTest) {
12803cab2bb3Spatrick static char a[100];
12813cab2bb3Spatrick static char b[100];
12823cab2bb3Spatrick static char c[100];
12833cab2bb3Spatrick Ident(a);
12843cab2bb3Spatrick Ident(b);
12853cab2bb3Spatrick Ident(c);
12863cab2bb3Spatrick Ident(a)[5] = 0;
12873cab2bb3Spatrick Ident(b)[105] = 0;
12883cab2bb3Spatrick Ident(a)[5] = 0;
12893cab2bb3Spatrick }
12903cab2bb3Spatrick
TEST(AddressSanitizer,DISABLED_DemoTooMuchMemoryTest)12913cab2bb3Spatrick TEST(AddressSanitizer, DISABLED_DemoTooMuchMemoryTest) {
12923cab2bb3Spatrick const size_t kAllocSize = (1 << 28) - 1024;
12933cab2bb3Spatrick size_t total_size = 0;
12943cab2bb3Spatrick while (true) {
12953cab2bb3Spatrick void *x = malloc(kAllocSize);
12963cab2bb3Spatrick memset(x, 0, kAllocSize);
12973cab2bb3Spatrick total_size += kAllocSize;
12983cab2bb3Spatrick fprintf(stderr, "total: %ldM %p\n", (long)total_size >> 20, x);
12993cab2bb3Spatrick }
13003cab2bb3Spatrick }
13013cab2bb3Spatrick
13023cab2bb3Spatrick #if !defined(__NetBSD__) && !defined(__i386__)
13033cab2bb3Spatrick // https://github.com/google/sanitizers/issues/66
TEST(AddressSanitizer,BufferOverflowAfterManyFrees)13043cab2bb3Spatrick TEST(AddressSanitizer, BufferOverflowAfterManyFrees) {
13053cab2bb3Spatrick for (int i = 0; i < 1000000; i++) {
13063cab2bb3Spatrick delete [] (Ident(new char [8644]));
13073cab2bb3Spatrick }
13083cab2bb3Spatrick char *x = new char[8192];
13093cab2bb3Spatrick EXPECT_DEATH(x[Ident(8192)] = 0, "AddressSanitizer: heap-buffer-overflow");
13103cab2bb3Spatrick delete [] Ident(x);
13113cab2bb3Spatrick }
13123cab2bb3Spatrick #endif
13133cab2bb3Spatrick
13143cab2bb3Spatrick
13153cab2bb3Spatrick // Test that instrumentation of stack allocations takes into account
13163cab2bb3Spatrick // AllocSize of a type, and not its StoreSize (16 vs 10 bytes for long double).
13173cab2bb3Spatrick // See http://llvm.org/bugs/show_bug.cgi?id=12047 for more details.
TEST(AddressSanitizer,LongDoubleNegativeTest)13183cab2bb3Spatrick TEST(AddressSanitizer, LongDoubleNegativeTest) {
13193cab2bb3Spatrick long double a, b;
13203cab2bb3Spatrick static long double c;
13213cab2bb3Spatrick memcpy(Ident(&a), Ident(&b), sizeof(long double));
13223cab2bb3Spatrick memcpy(Ident(&c), Ident(&b), sizeof(long double));
13233cab2bb3Spatrick }
13243cab2bb3Spatrick
13253cab2bb3Spatrick #if !defined(_WIN32)
TEST(AddressSanitizer,pthread_getschedparam)13263cab2bb3Spatrick TEST(AddressSanitizer, pthread_getschedparam) {
13273cab2bb3Spatrick int policy;
13283cab2bb3Spatrick struct sched_param param;
13293cab2bb3Spatrick EXPECT_DEATH(
13303cab2bb3Spatrick pthread_getschedparam(pthread_self(), &policy, Ident(¶m) + 2),
13313cab2bb3Spatrick "AddressSanitizer: stack-buffer-.*flow");
13323cab2bb3Spatrick EXPECT_DEATH(
13333cab2bb3Spatrick pthread_getschedparam(pthread_self(), Ident(&policy) - 1, ¶m),
13343cab2bb3Spatrick "AddressSanitizer: stack-buffer-.*flow");
13353cab2bb3Spatrick int res = pthread_getschedparam(pthread_self(), &policy, ¶m);
13363cab2bb3Spatrick ASSERT_EQ(0, res);
13373cab2bb3Spatrick }
13383cab2bb3Spatrick #endif
13393cab2bb3Spatrick
13403cab2bb3Spatrick #if SANITIZER_TEST_HAS_PRINTF_L
vsnprintf_l_wrapper(char * s,size_t n,locale_t l,const char * format,...)13413cab2bb3Spatrick static int vsnprintf_l_wrapper(char *s, size_t n,
13423cab2bb3Spatrick locale_t l, const char *format, ...) {
13433cab2bb3Spatrick va_list va;
13443cab2bb3Spatrick va_start(va, format);
13453cab2bb3Spatrick int res = vsnprintf_l(s, n , l, format, va);
13463cab2bb3Spatrick va_end(va);
13473cab2bb3Spatrick return res;
13483cab2bb3Spatrick }
13493cab2bb3Spatrick
TEST(AddressSanitizer,snprintf_l)13503cab2bb3Spatrick TEST(AddressSanitizer, snprintf_l) {
13513cab2bb3Spatrick char buff[5];
13523cab2bb3Spatrick // Check that snprintf_l() works fine with Asan.
13533cab2bb3Spatrick int res = snprintf_l(buff, 5, SANITIZER_GET_C_LOCALE, "%s", "snprintf_l()");
13543cab2bb3Spatrick EXPECT_EQ(12, res);
13553cab2bb3Spatrick // Check that vsnprintf_l() works fine with Asan.
13563cab2bb3Spatrick res = vsnprintf_l_wrapper(buff, 5, SANITIZER_GET_C_LOCALE, "%s",
13573cab2bb3Spatrick "vsnprintf_l()");
13583cab2bb3Spatrick EXPECT_EQ(13, res);
13593cab2bb3Spatrick
13603cab2bb3Spatrick EXPECT_DEATH(
13613cab2bb3Spatrick snprintf_l(buff, 10, SANITIZER_GET_C_LOCALE, "%s", "snprintf_l()"),
13623cab2bb3Spatrick "AddressSanitizer: stack-buffer-overflow");
13633cab2bb3Spatrick EXPECT_DEATH(vsnprintf_l_wrapper(buff, 10, SANITIZER_GET_C_LOCALE, "%s",
13643cab2bb3Spatrick "vsnprintf_l()"),
13653cab2bb3Spatrick "AddressSanitizer: stack-buffer-overflow");
13663cab2bb3Spatrick }
13673cab2bb3Spatrick #endif
1368