1394 lines · cpp
1//===-- asan_test.cpp -----------------------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// This file is a part of AddressSanitizer, an address sanity checker.10//11//===----------------------------------------------------------------------===//12#include "asan_test_utils.h"13 14#include <errno.h>15#include <stdarg.h>16 17#ifdef _LIBCPP_GET_C_LOCALE18#define SANITIZER_GET_C_LOCALE _LIBCPP_GET_C_LOCALE19#else20#if defined(__FreeBSD__)21#define SANITIZER_GET_C_LOCALE 022#elif defined(__NetBSD__)23#define SANITIZER_GET_C_LOCALE LC_C_LOCALE24#endif25#endif26 27#if defined(__sun__) && defined(__svr4__)28using std::_setjmp;29using std::_longjmp;30#endif31 32NOINLINE void *malloc_fff(size_t size) {33 void *res = malloc/**/(size); break_optimization(0); return res;}34NOINLINE void *malloc_eee(size_t size) {35 void *res = malloc_fff(size); break_optimization(0); return res;}36NOINLINE void *malloc_ddd(size_t size) {37 void *res = malloc_eee(size); break_optimization(0); return res;}38NOINLINE void *malloc_ccc(size_t size) {39 void *res = malloc_ddd(size); break_optimization(0); return res;}40NOINLINE void *malloc_bbb(size_t size) {41 void *res = malloc_ccc(size); break_optimization(0); return res;}42NOINLINE void *malloc_aaa(size_t size) {43 void *res = malloc_bbb(size); break_optimization(0); return res;}44 45NOINLINE void free_ccc(void *p) { free(p); break_optimization(0);}46NOINLINE void free_bbb(void *p) { free_ccc(p); break_optimization(0);}47NOINLINE void free_aaa(void *p) { free_bbb(p); break_optimization(0);}48 49template<typename T>50NOINLINE void uaf_test(int size, int off) {51 void *p = malloc_aaa(size);52 free_aaa(p);53 for (int i = 1; i < 100; i++)54 free_aaa(malloc_aaa(i));55 fprintf(stderr, "writing %ld byte(s) at %p with offset %d\n",56 (long)sizeof(T), p, off);57 asan_write((T *)((char *)p + off));58}59 60TEST(AddressSanitizer, HasFeatureAddressSanitizerTest) {61#if defined(__has_feature) && __has_feature(address_sanitizer)62 bool asan = 1;63#elif defined(__SANITIZE_ADDRESS__)64 bool asan = 1;65#else66 bool asan = 0;67#endif68 EXPECT_EQ(true, asan);69}70 71TEST(AddressSanitizer, SimpleDeathTest) {72 EXPECT_DEATH(exit(1), "");73}74 75TEST(AddressSanitizer, VariousMallocsTest) {76 int *a = (int*)malloc(100 * sizeof(int));77 a[50] = 0;78 free(a);79 80 int *r = (int*)malloc(10);81 r = (int*)realloc(r, 2000 * sizeof(int));82 r[1000] = 0;83 free(r);84 85 int *b = new int[100];86 b[50] = 0;87 delete [] b;88 89 int *c = new int;90 *c = 0;91 delete c;92 93#if SANITIZER_TEST_HAS_POSIX_MEMALIGN94 void *pm = 0;95 // Valid allocation.96 int pm_res = posix_memalign(&pm, kPageSize, kPageSize);97 EXPECT_EQ(0, pm_res);98 EXPECT_NE(nullptr, pm);99 free(pm);100#endif // SANITIZER_TEST_HAS_POSIX_MEMALIGN101 102#if SANITIZER_TEST_HAS_MEMALIGN103 int *ma = (int*)memalign(kPageSize, kPageSize);104 EXPECT_EQ(0U, (uintptr_t)ma % kPageSize);105 ma[123] = 0;106 free(ma);107#endif // SANITIZER_TEST_HAS_MEMALIGN108}109 110TEST(AddressSanitizer, CallocTest) {111 int *a = (int*)calloc(100, sizeof(int));112 EXPECT_EQ(0, a[10]);113 free(a);114}115 116TEST(AddressSanitizer, CallocReturnsZeroMem) {117 size_t sizes[] = {16, 1000, 10000, 100000, 2100000};118 for (size_t s = 0; s < sizeof(sizes)/sizeof(sizes[0]); s++) {119 size_t size = sizes[s];120 for (size_t iter = 0; iter < 5; iter++) {121 char *x = Ident((char*)calloc(1, size));122 EXPECT_EQ(x[0], 0);123 EXPECT_EQ(x[size - 1], 0);124 EXPECT_EQ(x[size / 2], 0);125 EXPECT_EQ(x[size / 3], 0);126 EXPECT_EQ(x[size / 4], 0);127 memset(x, 0x42, size);128 free(Ident(x));129#if !defined(_WIN32)130 // FIXME: OOM on Windows. We should just make this a lit test131 // with quarantine size set to 1.132 free(Ident(malloc(Ident(1 << 27)))); // Try to drain the quarantine.133#endif134 }135 }136}137 138// No valloc on Windows or Android.139#if !defined(_WIN32) && !defined(__ANDROID__)140TEST(AddressSanitizer, VallocTest) {141 void *a = valloc(100);142 EXPECT_EQ(0U, (uintptr_t)a % kPageSize);143 free(a);144}145#endif146 147#if SANITIZER_TEST_HAS_PVALLOC148TEST(AddressSanitizer, PvallocTest) {149 char *a = (char*)pvalloc(kPageSize + 100);150 EXPECT_EQ(0U, (uintptr_t)a % kPageSize);151 a[kPageSize + 101] = 1; // we should not report an error here.152 free(a);153 154 a = (char*)pvalloc(0); // pvalloc(0) should allocate at least one page.155 EXPECT_EQ(0U, (uintptr_t)a % kPageSize);156 a[101] = 1; // we should not report an error here.157 free(a);158}159#endif // SANITIZER_TEST_HAS_PVALLOC160 161#if !defined(_WIN32)162// FIXME: Use an equivalent of pthread_setspecific on Windows.163void *TSDWorker(void *test_key) {164 if (test_key) {165 pthread_setspecific(*(pthread_key_t*)test_key, (void*)0xfeedface);166 }167 return NULL;168}169 170void TSDDestructor(void *tsd) {171 // Spawning a thread will check that the current thread id is not -1.172 pthread_t th;173 PTHREAD_CREATE(&th, NULL, TSDWorker, NULL);174 PTHREAD_JOIN(th, NULL);175}176 177// This tests triggers the thread-specific data destruction fiasco which occurs178// if we don't manage the TSD destructors ourselves. We create a new pthread179// key with a non-NULL destructor which is likely to be put after the destructor180// of AsanThread in the list of destructors.181// In this case the TSD for AsanThread will be destroyed before TSDDestructor182// is called for the child thread, and a CHECK will fail when we call183// pthread_create() to spawn the grandchild.184TEST(AddressSanitizer, DISABLED_TSDTest) {185 pthread_t th;186 pthread_key_t test_key;187 pthread_key_create(&test_key, TSDDestructor);188 PTHREAD_CREATE(&th, NULL, TSDWorker, &test_key);189 PTHREAD_JOIN(th, NULL);190 pthread_key_delete(test_key);191}192#endif193 194TEST(AddressSanitizer, UAF_char) {195 const char *uaf_string = "AddressSanitizer:.*heap-use-after-free";196 EXPECT_DEATH(uaf_test<U1>(1, 0), uaf_string);197 EXPECT_DEATH(uaf_test<U1>(10, 0), uaf_string);198 EXPECT_DEATH(uaf_test<U1>(10, 10), uaf_string);199 EXPECT_DEATH(uaf_test<U1>(kLargeMalloc, 0), uaf_string);200 EXPECT_DEATH(uaf_test<U1>(kLargeMalloc, kLargeMalloc / 2), uaf_string);201}202 203TEST(AddressSanitizer, UAF_long_double) {204 if (sizeof(long double) == sizeof(double)) return;205 long double *p = Ident(new long double[10]);206#if defined(_WIN32)207 // https://google.github.io/googletest/advanced.html#regular-expression-syntax208 // GoogleTest's regular expression engine on Windows does not support `[]`209 // brackets.210 EXPECT_DEATH(Ident(p)[12] = 0, "WRITE of size 10");211 EXPECT_DEATH(Ident(p)[0] = Ident(p)[12], "READ of size 10");212#else213 EXPECT_DEATH(Ident(p)[12] = 0, "WRITE of size 1[026]");214 EXPECT_DEATH(Ident(p)[0] = Ident(p)[12], "READ of size 1[026]");215#endif216 delete [] Ident(p);217}218 219#if !defined(_WIN32)220struct Packed5 {221 int x;222 char c;223} __attribute__((packed));224#else225# pragma pack(push, 1)226struct Packed5 {227 int x;228 char c;229};230# pragma pack(pop)231#endif232 233TEST(AddressSanitizer, UAF_Packed5) {234 static_assert(sizeof(Packed5) == 5, "Please check the keywords used");235 Packed5 *p = Ident(new Packed5[2]);236 EXPECT_DEATH(p[0] = p[3], "READ of size 5");237 EXPECT_DEATH(p[3] = p[0], "WRITE of size 5");238 delete [] Ident(p);239}240 241#if ASAN_HAS_IGNORELIST242TEST(AddressSanitizer, IgnoreTest) {243 int *x = Ident(new int);244 delete Ident(x);245 *x = 0;246}247#endif // ASAN_HAS_IGNORELIST248 249struct StructWithBitField {250 int bf1:1;251 int bf2:1;252 int bf3:1;253 int bf4:29;254};255 256TEST(AddressSanitizer, BitFieldPositiveTest) {257 StructWithBitField *x = new StructWithBitField;258 delete Ident(x);259 EXPECT_DEATH(x->bf1 = 0, "use-after-free");260 EXPECT_DEATH(x->bf2 = 0, "use-after-free");261 EXPECT_DEATH(x->bf3 = 0, "use-after-free");262 EXPECT_DEATH(x->bf4 = 0, "use-after-free");263}264 265struct StructWithBitFields_8_24 {266 int a:8;267 int b:24;268};269 270TEST(AddressSanitizer, BitFieldNegativeTest) {271 StructWithBitFields_8_24 *x = Ident(new StructWithBitFields_8_24);272 x->a = 0;273 x->b = 0;274 delete Ident(x);275}276 277#if ASAN_NEEDS_SEGV278namespace {279 280const char kSEGVCrash[] = "AddressSanitizer: SEGV on unknown address";281const char kOverriddenSigactionHandler[] = "Test sigaction handler\n";282const char kOverriddenSignalHandler[] = "Test signal handler\n";283 284TEST(AddressSanitizer, WildAddressTest) {285 char *c = (char*)0x123;286 EXPECT_DEATH(*c = 0, kSEGVCrash);287}288 289void my_sigaction_sighandler(int, siginfo_t*, void*) {290 fprintf(stderr, kOverriddenSigactionHandler);291 exit(1);292}293 294void my_signal_sighandler(int signum) {295 fprintf(stderr, kOverriddenSignalHandler);296 exit(1);297}298 299TEST(AddressSanitizer, SignalTest) {300 struct sigaction sigact;301 memset(&sigact, 0, sizeof(sigact));302 sigact.sa_sigaction = my_sigaction_sighandler;303 sigact.sa_flags = SA_SIGINFO;304 char *c = (char *)0x123;305 306 EXPECT_DEATH(*c = 0, kSEGVCrash);307 308 // ASan should allow to set sigaction()...309 EXPECT_EQ(0, sigaction(SIGSEGV, &sigact, 0));310#ifdef __APPLE__311 EXPECT_EQ(0, sigaction(SIGBUS, &sigact, 0));312#endif313 EXPECT_DEATH(*c = 0, kOverriddenSigactionHandler);314 315 // ... and signal().316 EXPECT_NE(SIG_ERR, signal(SIGSEGV, my_signal_sighandler));317 EXPECT_DEATH(*c = 0, kOverriddenSignalHandler);318}319} // namespace320#endif321 322static void TestLargeMalloc(size_t size) {323 char buff[1024];324 sprintf(buff, "is located 1 bytes before %lu-byte", (long)size);325 EXPECT_DEATH(Ident((char*)malloc(size))[-1] = 0, buff);326}327 328TEST(AddressSanitizer, LargeMallocTest) {329 const int max_size = (SANITIZER_WORDSIZE == 32) ? 1 << 26 : 1 << 28;330 for (int i = 113; i < max_size; i = i * 2 + 13) {331 TestLargeMalloc(i);332 }333}334 335#if !GTEST_USES_SIMPLE_RE336TEST(AddressSanitizer, HugeMallocTest) {337 if (SANITIZER_WORDSIZE != 64 || ASAN_AVOID_EXPENSIVE_TESTS) return;338 size_t n_megs = 4100;339 EXPECT_DEATH(Ident((char*)malloc(n_megs << 20))[-1] = 0,340 "is located 1 bytes before|"341 "AddressSanitizer failed to allocate");342}343#endif344 345#if SANITIZER_TEST_HAS_MEMALIGN346void MemalignRun(size_t align, size_t size, int idx) {347 char *p = (char *)memalign(align, size);348 Ident(p)[idx] = 0;349 free(p);350}351 352TEST(AddressSanitizer, memalign) {353 for (int align = 16; align <= (1 << 23); align *= 2) {354 size_t size = align * 5;355 EXPECT_DEATH(MemalignRun(align, size, -1),356 "is located 1 bytes before");357 EXPECT_DEATH(MemalignRun(align, size, size + 1),358 "is located 1 bytes after");359 }360}361#endif // SANITIZER_TEST_HAS_MEMALIGN362 363void *ManyThreadsWorker(void *a) {364 for (int iter = 0; iter < 100; iter++) {365 for (size_t size = 100; size < 2000; size *= 2) {366 free(Ident(malloc(size)));367 }368 }369 return 0;370}371 372#if !defined(__powerpc64__)373// FIXME: Also occasional hang on powerpc. Maybe same problem as on AArch64?374TEST(AddressSanitizer, ManyThreadsTest) {375 const size_t kNumThreads =376 (SANITIZER_WORDSIZE == 32 || ASAN_AVOID_EXPENSIVE_TESTS) ? 30 : 1000;377 pthread_t t[kNumThreads];378 for (size_t i = 0; i < kNumThreads; i++) {379 PTHREAD_CREATE(&t[i], 0, ManyThreadsWorker, (void*)i);380 }381 for (size_t i = 0; i < kNumThreads; i++) {382 PTHREAD_JOIN(t[i], 0);383 }384}385#endif386 387TEST(AddressSanitizer, ReallocTest) {388 const int kMinElem = 5;389 int *ptr = (int*)malloc(sizeof(int) * kMinElem);390 ptr[3] = 3;391 for (int i = 0; i < 10000; i++) {392 ptr = (int*)realloc(ptr,393 (my_rand() % 1000 + kMinElem) * sizeof(int));394 EXPECT_EQ(3, ptr[3]);395 }396 free(ptr);397 // Realloc pointer returned by malloc(0).398 void *ptr0 = malloc(0);399 int *ptr2 = Ident((int *)ptr0);400 ptr2 = Ident((int*)realloc(ptr2, sizeof(*ptr2)));401 *ptr2 = 42;402 EXPECT_EQ(42, *ptr2);403 free(ptr2);404}405 406TEST(AddressSanitizer, ReallocFreedPointerTest) {407 void *ptr = Ident(malloc(42));408 ASSERT_TRUE(NULL != ptr);409 free(ptr);410 EXPECT_DEATH(ptr = realloc(ptr, 77), "attempting double-free");411}412 413TEST(AddressSanitizer, ReallocInvalidPointerTest) {414 void *ptr = Ident(malloc(42));415 EXPECT_DEATH(ptr = realloc((int*)ptr + 1, 77), "attempting free.*not malloc");416 free(ptr);417}418 419TEST(AddressSanitizer, ZeroSizeMallocTest) {420 // Test that malloc(0) and similar functions don't return NULL.421 void *ptr = Ident(malloc(0));422 EXPECT_TRUE(NULL != ptr);423 free(ptr);424#if SANITIZER_TEST_HAS_POSIX_MEMALIGN425 int pm_res = posix_memalign(&ptr, 1<<20, 0);426 EXPECT_EQ(0, pm_res);427 EXPECT_TRUE(NULL != ptr);428 free(ptr);429#endif // SANITIZER_TEST_HAS_POSIX_MEMALIGN430 int *int_ptr = new int[0];431 int *int_ptr2 = new int[0];432 EXPECT_TRUE(NULL != int_ptr);433 EXPECT_TRUE(NULL != int_ptr2);434 EXPECT_NE(int_ptr, int_ptr2);435 delete[] int_ptr;436 delete[] int_ptr2;437}438 439#if SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE440static const char *kMallocUsableSizeErrorMsg =441 "AddressSanitizer: attempting to call malloc_usable_size()";442 443TEST(AddressSanitizer, MallocUsableSizeTest) {444 const size_t kArraySize = 100;445 char *array = Ident((char*)malloc(kArraySize));446 int *int_ptr = Ident(new int);447 EXPECT_EQ(0U, malloc_usable_size(NULL));448 EXPECT_EQ(kArraySize, malloc_usable_size(array));449 EXPECT_EQ(sizeof(int), malloc_usable_size(int_ptr));450 EXPECT_DEATH(malloc_usable_size((void*)0x123), kMallocUsableSizeErrorMsg);451 EXPECT_DEATH(malloc_usable_size(array + kArraySize / 2),452 kMallocUsableSizeErrorMsg);453 free(array);454 EXPECT_DEATH(malloc_usable_size(array), kMallocUsableSizeErrorMsg);455 delete int_ptr;456}457#endif // SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE458 459void WrongFree() {460 int *x = (int*)malloc(100 * sizeof(int));461 // Use the allocated memory, otherwise Clang will optimize it out.462 Ident(x);463 free(x + 1);464}465 466#if !defined(_WIN32) // FIXME: This should be a lit test.467TEST(AddressSanitizer, WrongFreeTest) {468 EXPECT_DEATH(WrongFree(), ASAN_PCRE_DOTALL469 "ERROR: AddressSanitizer: attempting free.*not malloc"470 ".*is located 4 bytes inside of 400-byte region"471 ".*allocated by thread");472}473#endif474 475void DoubleFree() {476 int *x = (int*)malloc(100 * sizeof(int));477 fprintf(stderr, "DoubleFree: x=%p\n", (void *)x);478 free(x);479 free(x);480 fprintf(stderr, "should have failed in the second free(%p)\n", (void *)x);481 abort();482}483 484#if !defined(_WIN32) // FIXME: This should be a lit test.485TEST(AddressSanitizer, DoubleFreeTest) {486 EXPECT_DEATH(DoubleFree(), ASAN_PCRE_DOTALL487 "ERROR: AddressSanitizer: attempting double-free"488 ".*is located 0 bytes inside of 400-byte region"489 ".*freed by thread T0 here"490 ".*previously allocated by thread T0 here");491}492#endif493 494template<int kSize>495NOINLINE void SizedStackTest() {496 char a[kSize];497 char *A = Ident((char*)&a);498 const char *expected_death = "AddressSanitizer: stack-buffer-";499 for (size_t i = 0; i < kSize; i++)500 A[i] = i;501 EXPECT_DEATH(A[-1] = 0, expected_death);502 EXPECT_DEATH(A[-5] = 0, expected_death);503 EXPECT_DEATH(A[kSize] = 0, expected_death);504 EXPECT_DEATH(A[kSize + 1] = 0, expected_death);505 EXPECT_DEATH(A[kSize + 5] = 0, expected_death);506 if (kSize > 16)507 EXPECT_DEATH(A[kSize + 31] = 0, expected_death);508}509 510TEST(AddressSanitizer, SimpleStackTest) {511 SizedStackTest<1>();512 SizedStackTest<2>();513 SizedStackTest<3>();514 SizedStackTest<4>();515 SizedStackTest<5>();516 SizedStackTest<6>();517 SizedStackTest<7>();518 SizedStackTest<16>();519 SizedStackTest<25>();520 SizedStackTest<34>();521 SizedStackTest<43>();522 SizedStackTest<51>();523 SizedStackTest<62>();524 SizedStackTest<64>();525 SizedStackTest<128>();526}527 528#if !defined(_WIN32)529// FIXME: It's a bit hard to write multi-line death test expectations530// in a portable way. Anyways, this should just be turned into a lit test.531TEST(AddressSanitizer, ManyStackObjectsTest) {532 char XXX[10];533 char YYY[20];534 char ZZZ[30];535 Ident(XXX);536 Ident(YYY);537 EXPECT_DEATH(Ident(ZZZ)[-1] = 0, ASAN_PCRE_DOTALL "XXX.*YYY.*ZZZ");538}539#endif540 541#if 0 // This test requires online symbolizer.542// Moved to lit_tests/stack-oob-frames.cpp.543// Reenable here once we have online symbolizer by default.544NOINLINE static void Frame0(int frame, char *a, char *b, char *c) {545 char d[4] = {0};546 char *D = Ident(d);547 switch (frame) {548 case 3: a[5]++; break;549 case 2: b[5]++; break;550 case 1: c[5]++; break;551 case 0: D[5]++; break;552 }553}554NOINLINE static void Frame1(int frame, char *a, char *b) {555 char c[4] = {0}; Frame0(frame, a, b, c);556 break_optimization(0);557}558NOINLINE static void Frame2(int frame, char *a) {559 char b[4] = {0}; Frame1(frame, a, b);560 break_optimization(0);561}562NOINLINE static void Frame3(int frame) {563 char a[4] = {0}; Frame2(frame, a);564 break_optimization(0);565}566 567TEST(AddressSanitizer, GuiltyStackFrame0Test) {568 EXPECT_DEATH(Frame3(0), "located .*in frame <.*Frame0");569}570TEST(AddressSanitizer, GuiltyStackFrame1Test) {571 EXPECT_DEATH(Frame3(1), "located .*in frame <.*Frame1");572}573TEST(AddressSanitizer, GuiltyStackFrame2Test) {574 EXPECT_DEATH(Frame3(2), "located .*in frame <.*Frame2");575}576TEST(AddressSanitizer, GuiltyStackFrame3Test) {577 EXPECT_DEATH(Frame3(3), "located .*in frame <.*Frame3");578}579#endif580 581NOINLINE void LongJmpFunc1(jmp_buf buf) {582 // create three red zones for these two stack objects.583 int a;584 int b;585 586 int *A = Ident(&a);587 int *B = Ident(&b);588 *A = *B;589 longjmp(buf, 1);590}591 592NOINLINE void TouchStackFunc() {593 int a[100]; // long array will intersect with redzones from LongJmpFunc1.594 int *A = Ident(a);595 for (int i = 0; i < 100; i++)596 A[i] = i*i;597}598 599// Test that we handle longjmp and do not report false positives on stack.600TEST(AddressSanitizer, LongJmpTest) {601 static jmp_buf buf;602 if (!setjmp(buf)) {603 LongJmpFunc1(buf);604 } else {605 TouchStackFunc();606 }607}608 609#if !defined(_WIN32) // Only basic longjmp is available on Windows.610NOINLINE void UnderscopeLongJmpFunc1(jmp_buf buf) {611 // create three red zones for these two stack objects.612 int a;613 int b;614 615 int *A = Ident(&a);616 int *B = Ident(&b);617 *A = *B;618 _longjmp(buf, 1);619}620 621NOINLINE void SigLongJmpFunc1(sigjmp_buf buf) {622 // create three red zones for these two stack objects.623 int a;624 int b;625 626 int *A = Ident(&a);627 int *B = Ident(&b);628 *A = *B;629 siglongjmp(buf, 1);630}631 632#if !defined(__ANDROID__) && !defined(__arm__) && !defined(__aarch64__) && \633 !defined(__mips__) && !defined(__mips64) && !defined(__s390__) && \634 !defined(__riscv) && !defined(__loongarch__) && !defined(__sparc__)635NOINLINE void BuiltinLongJmpFunc1(jmp_buf buf) {636 // create three red zones for these two stack objects.637 int a;638 int b;639 640 int *A = Ident(&a);641 int *B = Ident(&b);642 *A = *B;643 __builtin_longjmp((void**)buf, 1);644}645 646// Does not work on ARM:647// https://github.com/google/sanitizers/issues/185648TEST(AddressSanitizer, BuiltinLongJmpTest) {649 static jmp_buf buf;650 if (!__builtin_setjmp((void**)buf)) {651 BuiltinLongJmpFunc1(buf);652 } else {653 TouchStackFunc();654 }655}656#endif // !defined(__ANDROID__) && !defined(__arm__) &&657 // !defined(__aarch64__) && !defined(__mips__) &&658 // !defined(__mips64) && !defined(__s390__) &&659 // !defined(__riscv) && !defined(__loongarch__)660 661TEST(AddressSanitizer, UnderscopeLongJmpTest) {662 static jmp_buf buf;663 if (!_setjmp(buf)) {664 UnderscopeLongJmpFunc1(buf);665 } else {666 TouchStackFunc();667 }668}669 670TEST(AddressSanitizer, SigLongJmpTest) {671 static sigjmp_buf buf;672 if (!sigsetjmp(buf, 1)) {673 SigLongJmpFunc1(buf);674 } else {675 TouchStackFunc();676 }677}678#endif679 680// FIXME: Why does clang-cl define __EXCEPTIONS?681#if defined(__EXCEPTIONS) && !defined(_WIN32)682NOINLINE void ThrowFunc() {683 // create three red zones for these two stack objects.684 int a;685 int b;686 687 int *A = Ident(&a);688 int *B = Ident(&b);689 *A = *B;690 ASAN_THROW(1);691}692 693TEST(AddressSanitizer, CxxExceptionTest) {694 if (ASAN_UAR) return;695 // TODO(kcc): this test crashes on 32-bit for some reason...696 if (SANITIZER_WORDSIZE == 32) return;697 try {698 ThrowFunc();699 } catch(...) {}700 TouchStackFunc();701}702#endif703 704void *ThreadStackReuseFunc1(void *unused) {705 // create three red zones for these two stack objects.706 int a;707 int b;708 709 int *A = Ident(&a);710 int *B = Ident(&b);711 *A = *B;712 pthread_exit(0);713 return 0;714}715 716void *ThreadStackReuseFunc2(void *unused) {717 TouchStackFunc();718 return 0;719}720 721#if !defined(__thumb__)722TEST(AddressSanitizer, ThreadStackReuseTest) {723 pthread_t t;724 PTHREAD_CREATE(&t, 0, ThreadStackReuseFunc1, 0);725 PTHREAD_JOIN(t, 0);726 PTHREAD_CREATE(&t, 0, ThreadStackReuseFunc2, 0);727 PTHREAD_JOIN(t, 0);728}729#endif730 731#if defined(__SSE2__)732#include <emmintrin.h>733TEST(AddressSanitizer, Store128Test) {734 char *a = Ident((char*)malloc(Ident(12)));735 char *p = a;736 if (((uintptr_t)a % 16) != 0)737 p = a + 8;738 assert(((uintptr_t)p % 16) == 0);739 __m128i value_wide = _mm_set1_epi16(0x1234);740 EXPECT_DEATH(_mm_store_si128((__m128i*)p, value_wide),741 "AddressSanitizer: heap-buffer-overflow");742 EXPECT_DEATH(_mm_store_si128((__m128i*)p, value_wide),743 "WRITE of size 16");744 EXPECT_DEATH(_mm_store_si128((__m128i*)p, value_wide),745 "located 0 bytes after 12-byte");746 free(a);747}748#endif749 750// FIXME: All tests that use this function should be turned into lit tests.751std::string RightOOBErrorMessage(int oob_distance, bool is_write) {752 assert(oob_distance >= 0);753 char expected_str[100];754 sprintf(expected_str, ASAN_PCRE_DOTALL755#if !GTEST_USES_SIMPLE_RE756 "buffer-overflow.*%s.*"757#endif758 "located %d bytes after",759#if !GTEST_USES_SIMPLE_RE760 is_write ? "WRITE" : "READ",761#endif762 oob_distance);763 return std::string(expected_str);764}765 766std::string RightOOBWriteMessage(int oob_distance) {767 return RightOOBErrorMessage(oob_distance, /*is_write*/true);768}769 770std::string RightOOBReadMessage(int oob_distance) {771 return RightOOBErrorMessage(oob_distance, /*is_write*/false);772}773 774// FIXME: All tests that use this function should be turned into lit tests.775std::string LeftOOBErrorMessage(int oob_distance, bool is_write) {776 assert(oob_distance > 0);777 char expected_str[100];778 sprintf(expected_str,779#if !GTEST_USES_SIMPLE_RE780 ASAN_PCRE_DOTALL "%s.*"781#endif782 "located %d bytes before",783#if !GTEST_USES_SIMPLE_RE784 is_write ? "WRITE" : "READ",785#endif786 oob_distance);787 return std::string(expected_str);788}789 790std::string LeftOOBWriteMessage(int oob_distance) {791 return LeftOOBErrorMessage(oob_distance, /*is_write*/true);792}793 794std::string LeftOOBReadMessage(int oob_distance) {795 return LeftOOBErrorMessage(oob_distance, /*is_write*/false);796}797 798std::string LeftOOBAccessMessage(int oob_distance) {799 assert(oob_distance > 0);800 char expected_str[100];801 sprintf(expected_str, "located %d bytes before", oob_distance);802 return std::string(expected_str);803}804 805char* MallocAndMemsetString(size_t size, char ch) {806 char *s = Ident((char*)malloc(size));807 memset(s, ch, size);808 return s;809}810 811char* MallocAndMemsetString(size_t size) {812 return MallocAndMemsetString(size, 'z');813}814 815#if SANITIZER_GLIBC816#define READ_TEST(READ_N_BYTES) \817 char *x = new char[10]; \818 int fd = open("/proc/self/stat", O_RDONLY); \819 ASSERT_GT(fd, 0); \820 EXPECT_DEATH(READ_N_BYTES, \821 ASAN_PCRE_DOTALL \822 "AddressSanitizer: heap-buffer-overflow" \823 ".* is located 0 bytes after 10-byte region"); \824 close(fd); \825 delete [] x; \826 827TEST(AddressSanitizer, pread) {828 READ_TEST(pread(fd, x, 15, 0));829}830 831TEST(AddressSanitizer, pread64) {832 READ_TEST(pread64(fd, x, 15, 0));833}834 835TEST(AddressSanitizer, read) {836 READ_TEST(read(fd, x, 15));837}838#endif // SANITIZER_GLIBC839 840// This test case fails841// Clang optimizes memcpy/memset calls which lead to unaligned access842TEST(AddressSanitizer, DISABLED_MemIntrinsicUnalignedAccessTest) {843 int size = Ident(4096);844 char *s = Ident((char*)malloc(size));845 EXPECT_DEATH(memset(s + size - 1, 0, 2), RightOOBWriteMessage(0));846 free(s);847}848 849NOINLINE static int LargeFunction(bool do_bad_access) {850 int *x = new int[100];851 x[0]++;852 x[1]++;853 x[2]++;854 x[3]++;855 x[4]++;856 x[5]++;857 x[6]++;858 x[7]++;859 x[8]++;860 x[9]++;861 862 x[do_bad_access ? 100 : 0]++; int res = __LINE__;863 864 x[10]++;865 x[11]++;866 x[12]++;867 x[13]++;868 x[14]++;869 x[15]++;870 x[16]++;871 x[17]++;872 x[18]++;873 x[19]++;874 875 delete[] x;876 return res;877}878 879// Test the we have correct debug info for the failing instruction.880// This test requires the in-process symbolizer to be enabled by default.881TEST(AddressSanitizer, DISABLED_LargeFunctionSymbolizeTest) {882 int failing_line = LargeFunction(false);883 char expected_warning[128];884 sprintf(expected_warning, "LargeFunction.*asan_test.*:%d", failing_line);885 EXPECT_DEATH(LargeFunction(true), expected_warning);886}887 888// Check that we unwind and symbolize correctly.889TEST(AddressSanitizer, DISABLED_MallocFreeUnwindAndSymbolizeTest) {890 int *a = (int*)malloc_aaa(sizeof(int));891 *a = 1;892 free_aaa(a);893 EXPECT_DEATH(*a = 1, "free_ccc.*free_bbb.*free_aaa.*"894 "malloc_fff.*malloc_eee.*malloc_ddd");895}896 897static bool TryToSetThreadName(const char *name) {898#if defined(__linux__) && defined(PR_SET_NAME)899 return 0 == prctl(PR_SET_NAME, (unsigned long)name, 0, 0, 0);900#else901 return false;902#endif903}904 905void *ThreadedTestAlloc(void *a) {906 EXPECT_EQ(true, TryToSetThreadName("AllocThr"));907 int **p = (int**)a;908 *p = new int;909 return 0;910}911 912void *ThreadedTestFree(void *a) {913 EXPECT_EQ(true, TryToSetThreadName("FreeThr"));914 int **p = (int**)a;915 delete *p;916 return 0;917}918 919void *ThreadedTestUse(void *a) {920 EXPECT_EQ(true, TryToSetThreadName("UseThr"));921 int **p = (int**)a;922 **p = 1;923 return 0;924}925 926void ThreadedTestSpawn() {927 pthread_t t;928 int *x;929 PTHREAD_CREATE(&t, 0, ThreadedTestAlloc, &x);930 PTHREAD_JOIN(t, 0);931 PTHREAD_CREATE(&t, 0, ThreadedTestFree, &x);932 PTHREAD_JOIN(t, 0);933 PTHREAD_CREATE(&t, 0, ThreadedTestUse, &x);934 PTHREAD_JOIN(t, 0);935}936 937#if !defined(_WIN32) // FIXME: This should be a lit test.938TEST(AddressSanitizer, ThreadedTest) {939 EXPECT_DEATH(ThreadedTestSpawn(),940 ASAN_PCRE_DOTALL941 "Thread T.*created"942 ".*Thread T.*created"943 ".*Thread T.*created");944}945#endif946 947void *ThreadedTestFunc(void *unused) {948 // Check if prctl(PR_SET_NAME) is supported. Return if not.949 if (!TryToSetThreadName("TestFunc"))950 return 0;951 EXPECT_DEATH(ThreadedTestSpawn(),952 ASAN_PCRE_DOTALL953 "WRITE .*thread T. .UseThr."954 ".*freed by thread T. .FreeThr. here:"955 ".*previously allocated by thread T. .AllocThr. here:"956 ".*Thread T. .UseThr. created by T.*TestFunc"957 ".*Thread T. .FreeThr. created by T"958 ".*Thread T. .AllocThr. created by T"959 "");960 return 0;961}962 963TEST(AddressSanitizer, ThreadNamesTest) {964 // Run ThreadedTestFunc in a separate thread because it tries to set a965 // thread name and we don't want to change the main thread's name.966 pthread_t t;967 PTHREAD_CREATE(&t, 0, ThreadedTestFunc, 0);968 PTHREAD_JOIN(t, 0);969}970 971#if ASAN_NEEDS_SEGV972TEST(AddressSanitizer, ShadowGapTest) {973#if SANITIZER_WORDSIZE == 32974 char *addr = (char*)0x23000000;975#else976# if defined(__powerpc64__)977 char *addr = (char*)0x024000800000;978# elif defined(__s390x__)979 char *addr = (char*)0x11000000000000;980# else981 char *addr = (char*)0x0000100000080000;982# endif983#endif984 EXPECT_DEATH(*addr = 1, "AddressSanitizer: (SEGV|BUS) on unknown");985}986#endif // ASAN_NEEDS_SEGV987 988extern "C" {989NOINLINE static void UseThenFreeThenUse() {990 char *x = Ident((char*)malloc(8));991 *x = 1;992 free_aaa(x);993 *x = 2;994}995}996 997TEST(AddressSanitizer, UseThenFreeThenUseTest) {998 EXPECT_DEATH(UseThenFreeThenUse(), "freed by thread");999}1000 1001TEST(AddressSanitizer, StrDupTest) {1002 free(strdup(Ident("123")));1003}1004 1005// Currently we create and poison redzone at right of global variables.1006static char static110[110];1007const char ConstGlob[7] = {1, 2, 3, 4, 5, 6, 7};1008static const char StaticConstGlob[3] = {9, 8, 7};1009 1010TEST(AddressSanitizer, GlobalTest) {1011 static char func_static15[15];1012 1013 static char fs1[10];1014 static char fs2[10];1015 static char fs3[10];1016 1017 glob5[Ident(0)] = 0;1018 glob5[Ident(1)] = 0;1019 glob5[Ident(2)] = 0;1020 glob5[Ident(3)] = 0;1021 glob5[Ident(4)] = 0;1022 1023 EXPECT_DEATH(glob5[Ident(5)] = 0,1024 "0 bytes after global variable.*glob5.* size 5");1025 EXPECT_DEATH(glob5[Ident(5+6)] = 0,1026 "6 bytes after global variable.*glob5.* size 5");1027 Ident(static110); // avoid optimizations1028 static110[Ident(0)] = 0;1029 static110[Ident(109)] = 0;1030 EXPECT_DEATH(static110[Ident(110)] = 0,1031 "0 bytes after global variable");1032 EXPECT_DEATH(static110[Ident(110+7)] = 0,1033 "7 bytes after global variable");1034 1035 Ident(func_static15); // avoid optimizations1036 func_static15[Ident(0)] = 0;1037 EXPECT_DEATH(func_static15[Ident(15)] = 0,1038 "0 bytes after global variable");1039 EXPECT_DEATH(func_static15[Ident(15 + 9)] = 0,1040 "9 bytes after global variable");1041 1042 Ident(fs1);1043 Ident(fs2);1044 Ident(fs3);1045 1046 // We don't create left redzones, so this is not 100% guaranteed to fail.1047 // But most likely will.1048 EXPECT_DEATH(fs2[Ident(-1)] = 0, "is located.* global variable");1049 1050 EXPECT_DEATH(Ident(Ident(ConstGlob)[8]),1051 "is located 1 bytes after .*ConstGlob");1052 EXPECT_DEATH(Ident(Ident(StaticConstGlob)[5]),1053 "is located 2 bytes after .*StaticConstGlob");1054 1055 // call stuff from another file.1056 GlobalsTest(0);1057}1058 1059TEST(AddressSanitizer, GlobalStringConstTest) {1060 static const char *zoo = "FOOBAR123";1061 const char *p = Ident(zoo);1062 EXPECT_DEATH(Ident(p[15]), "is ascii string 'FOOBAR123'");1063}1064 1065TEST(AddressSanitizer, FileNameInGlobalReportTest) {1066 static char zoo[10];1067 const char *p = Ident(zoo);1068 // The file name should be present in the report.1069 EXPECT_DEATH(Ident(p[15]), "zoo.*asan_test.");1070}1071 1072int *ReturnsPointerToALocalObject() {1073 int a = 0;1074 return Ident(&a);1075}1076 1077#if ASAN_UAR == 11078TEST(AddressSanitizer, LocalReferenceReturnTest) {1079 int *(*f)() = Ident(ReturnsPointerToALocalObject);1080 int *p = f();1081 // Call 'f' a few more times, 'p' should still be poisoned.1082 for (int i = 0; i < 32; i++)1083 f();1084 EXPECT_DEATH(*p = 1, "AddressSanitizer: stack-use-after-return");1085 EXPECT_DEATH(*p = 1, "is located.*in frame .*ReturnsPointerToALocal");1086}1087#endif1088 1089template <int kSize>1090NOINLINE static void FuncWithStack() {1091 char x[kSize];1092 Ident(x)[0] = 0;1093 Ident(x)[kSize-1] = 0;1094}1095 1096static void LotsOfStackReuse() {1097 int LargeStack[10000];1098 Ident(LargeStack)[0] = 0;1099 for (int i = 0; i < 10000; i++) {1100 FuncWithStack<128 * 1>();1101 FuncWithStack<128 * 2>();1102 FuncWithStack<128 * 4>();1103 FuncWithStack<128 * 8>();1104 FuncWithStack<128 * 16>();1105 FuncWithStack<128 * 32>();1106 FuncWithStack<128 * 64>();1107 FuncWithStack<128 * 128>();1108 FuncWithStack<128 * 256>();1109 FuncWithStack<128 * 512>();1110 Ident(LargeStack)[0] = 0;1111 }1112}1113 1114TEST(AddressSanitizer, StressStackReuseTest) {1115 LotsOfStackReuse();1116}1117 1118// On some platform (ex: AIX), the default thread stack size (~96 KB) is1119// insufficient for this test and can lead to stack overflows.1120#define MIN_STACK_SIZE (128 * 1024) // 128 KB1121TEST(AddressSanitizer, ThreadedStressStackReuseTest) {1122 const int kNumThreads = 20;1123 pthread_t t[kNumThreads];1124// pthread_attr isn't supported on Windows.1125#ifndef _WIN321126 size_t curStackSize = 0;1127 pthread_attr_t attr;1128 pthread_attr_init(&attr);1129 // Get the current (default) thread stack size1130 pthread_attr_getstacksize(&attr, &curStackSize);1131 if (curStackSize < MIN_STACK_SIZE) {1132 int rc = pthread_attr_setstacksize(&attr, MIN_STACK_SIZE);1133 ASSERT_EQ(0, rc);1134 }1135#endif1136 for (int i = 0; i < kNumThreads; i++) {1137#ifdef _WIN321138 PTHREAD_CREATE(&t[i], 0, (void* (*)(void* x))LotsOfStackReuse, 0);1139#else1140 PTHREAD_CREATE(&t[i], &attr, (void* (*)(void* x))LotsOfStackReuse, 0);1141#endif1142 }1143 for (int i = 0; i < kNumThreads; i++) {1144 PTHREAD_JOIN(t[i], 0);1145 }1146#ifndef _WIN321147 pthread_attr_destroy(&attr);1148#endif1149}1150 1151// pthread_exit tries to perform unwinding stuff that leads to dlopen'ing1152// libgcc_s.so. dlopen in its turn calls malloc to store "libgcc_s.so" string1153// that confuses LSan on Thumb because it fails to understand that this1154// allocation happens in dynamic linker and should be ignored.1155#if !defined(__thumb__)1156static void *PthreadExit(void *a) {1157 pthread_exit(0);1158 return 0;1159}1160 1161TEST(AddressSanitizer, PthreadExitTest) {1162 pthread_t t;1163 for (int i = 0; i < 1000; i++) {1164 PTHREAD_CREATE(&t, 0, PthreadExit, 0);1165 PTHREAD_JOIN(t, 0);1166 }1167}1168#endif1169 1170// FIXME: Why does clang-cl define __EXCEPTIONS?1171#if defined(__EXCEPTIONS) && !defined(_WIN32)1172NOINLINE static void StackReuseAndException() {1173 int large_stack[1000];1174 Ident(large_stack);1175 ASAN_THROW(1);1176}1177 1178// TODO(kcc): support exceptions with use-after-return.1179TEST(AddressSanitizer, DISABLED_StressStackReuseAndExceptionsTest) {1180 for (int i = 0; i < 10000; i++) {1181 try {1182 StackReuseAndException();1183 } catch(...) {1184 }1185 }1186}1187#endif1188 1189#if !defined(_WIN32) && !defined(__HAIKU__)1190TEST(AddressSanitizer, MlockTest) {1191 EXPECT_EQ(0, mlockall(MCL_CURRENT));1192 EXPECT_EQ(0, mlock((void *)0x12345, 0x5678));1193 EXPECT_EQ(0, munlockall());1194 EXPECT_EQ(0, munlock((void*)0x987, 0x654));1195}1196#endif1197 1198struct LargeStruct {1199 int foo[100];1200};1201 1202// Test for bug http://llvm.org/bugs/show_bug.cgi?id=11763.1203// Struct copy should not cause asan warning even if lhs == rhs.1204TEST(AddressSanitizer, LargeStructCopyTest) {1205 LargeStruct a;1206 *Ident(&a) = *Ident(&a);1207}1208 1209ATTRIBUTE_NO_SANITIZE_ADDRESS1210static void NoSanitizeAddress() {1211 char *foo = new char[10];1212 Ident(foo)[10] = 0;1213 delete [] foo;1214}1215 1216TEST(AddressSanitizer, AttributeNoSanitizeAddressTest) {1217 Ident(NoSanitizeAddress)();1218}1219 1220// The new/delete/etc mismatch checks don't work on Android,1221// as calls to new/delete go through malloc/free.1222// OS X support is tracked here:1223// https://github.com/google/sanitizers/issues/1311224// Windows support is tracked here:1225// https://github.com/google/sanitizers/issues/3091226#if !defined(__ANDROID__) && \1227 !defined(__APPLE__) && \1228 !defined(_WIN32)1229static std::string MismatchStr(const std::string &str) {1230 return std::string("AddressSanitizer: alloc-dealloc-mismatch \\(") + str;1231}1232 1233static std::string MismatchOrNewDeleteTypeStr(const std::string &mismatch_str) {1234 return "(" + MismatchStr(mismatch_str) +1235 ")|(AddressSanitizer: new-delete-type-mismatch)";1236}1237 1238TEST(AddressSanitizer, AllocDeallocMismatch) {1239 EXPECT_DEATH(free(Ident(new int)),1240 MismatchStr("operator new vs free"));1241 EXPECT_DEATH(free(Ident(new int[2])),1242 MismatchStr("operator new \\[\\] vs free"));1243 EXPECT_DEATH(1244 delete (Ident(new int[2])),1245 MismatchOrNewDeleteTypeStr("operator new \\[\\] vs operator delete"));1246 EXPECT_DEATH(delete (Ident((int *)malloc(2 * sizeof(int)))),1247 MismatchOrNewDeleteTypeStr("malloc vs operator delete"));1248 EXPECT_DEATH(delete [] (Ident(new int)),1249 MismatchStr("operator new vs operator delete \\[\\]"));1250 EXPECT_DEATH(delete [] (Ident((int*)malloc(2 * sizeof(int)))),1251 MismatchStr("malloc vs operator delete \\[\\]"));1252}1253#endif1254 1255// ------------------ demo tests; run each one-by-one -------------1256// e.g. --gtest_filter=*DemoOOBLeftHigh --gtest_also_run_disabled_tests1257TEST(AddressSanitizer, DISABLED_DemoThreadedTest) {1258 ThreadedTestSpawn();1259}1260 1261void *SimpleBugOnSTack(void *x = 0) {1262 char a[20];1263 Ident(a)[20] = 0;1264 return 0;1265}1266 1267TEST(AddressSanitizer, DISABLED_DemoStackTest) {1268 SimpleBugOnSTack();1269}1270 1271TEST(AddressSanitizer, DISABLED_DemoThreadStackTest) {1272 pthread_t t;1273 PTHREAD_CREATE(&t, 0, SimpleBugOnSTack, 0);1274 PTHREAD_JOIN(t, 0);1275}1276 1277TEST(AddressSanitizer, DISABLED_DemoUAFLowIn) {1278 uaf_test<U1>(10, 0);1279}1280TEST(AddressSanitizer, DISABLED_DemoUAFLowLeft) {1281 uaf_test<U1>(10, -2);1282}1283TEST(AddressSanitizer, DISABLED_DemoUAFLowRight) {1284 uaf_test<U1>(10, 10);1285}1286 1287TEST(AddressSanitizer, DISABLED_DemoUAFHigh) {1288 uaf_test<U1>(kLargeMalloc, 0);1289}1290 1291TEST(AddressSanitizer, DISABLED_DemoOOM) {1292 size_t size = SANITIZER_WORDSIZE == 64 ? (size_t)(1ULL << 40) : (0xf0000000);1293 printf("%p\n", malloc(size));1294}1295 1296TEST(AddressSanitizer, DISABLED_DemoDoubleFreeTest) {1297 DoubleFree();1298}1299 1300TEST(AddressSanitizer, DISABLED_DemoNullDerefTest) {1301 int *a = 0;1302 Ident(a)[10] = 0;1303}1304 1305TEST(AddressSanitizer, DISABLED_DemoFunctionStaticTest) {1306 static char a[100];1307 static char b[100];1308 static char c[100];1309 Ident(a);1310 Ident(b);1311 Ident(c);1312 Ident(a)[5] = 0;1313 Ident(b)[105] = 0;1314 Ident(a)[5] = 0;1315}1316 1317TEST(AddressSanitizer, DISABLED_DemoTooMuchMemoryTest) {1318 const size_t kAllocSize = (1 << 28) - 1024;1319 size_t total_size = 0;1320 while (true) {1321 void *x = malloc(kAllocSize);1322 memset(x, 0, kAllocSize);1323 total_size += kAllocSize;1324 fprintf(stderr, "total: %ldM %p\n", (long)total_size >> 20, x);1325 }1326}1327 1328#if !defined(__NetBSD__) && !defined(__i386__)1329// https://github.com/google/sanitizers/issues/661330TEST(AddressSanitizer, BufferOverflowAfterManyFrees) {1331 for (int i = 0; i < 1000000; i++) {1332 delete [] (Ident(new char [8644]));1333 }1334 char *x = new char[8192];1335 EXPECT_DEATH(x[Ident(8192)] = 0, "AddressSanitizer: heap-buffer-overflow");1336 delete [] Ident(x);1337}1338#endif1339 1340 1341// Test that instrumentation of stack allocations takes into account1342// AllocSize of a type, and not its StoreSize (16 vs 10 bytes for long double).1343// See http://llvm.org/bugs/show_bug.cgi?id=12047 for more details.1344TEST(AddressSanitizer, LongDoubleNegativeTest) {1345 long double a, b;1346 static long double c;1347 memcpy(Ident(&a), Ident(&b), sizeof(long double));1348 memcpy(Ident(&c), Ident(&b), sizeof(long double));1349}1350 1351#if !defined(_WIN32)1352TEST(AddressSanitizer, pthread_getschedparam) {1353 int policy;1354 struct sched_param param;1355 EXPECT_DEATH(1356 pthread_getschedparam(pthread_self(), &policy, Ident(¶m) + 2),1357 "AddressSanitizer: stack-buffer-.*flow");1358 EXPECT_DEATH(1359 pthread_getschedparam(pthread_self(), Ident(&policy) - 1, ¶m),1360 "AddressSanitizer: stack-buffer-.*flow");1361 int res = pthread_getschedparam(pthread_self(), &policy, ¶m);1362 ASSERT_EQ(0, res);1363}1364#endif1365 1366#if SANITIZER_TEST_HAS_PRINTF_L1367static int vsnprintf_l_wrapper(char *s, size_t n,1368 locale_t l, const char *format, ...) {1369 va_list va;1370 va_start(va, format);1371 int res = vsnprintf_l(s, n , l, format, va);1372 va_end(va);1373 return res;1374}1375 1376TEST(AddressSanitizer, snprintf_l) {1377 char buff[5];1378 // Check that snprintf_l() works fine with Asan.1379 int res = snprintf_l(buff, 5, SANITIZER_GET_C_LOCALE, "%s", "snprintf_l()");1380 EXPECT_EQ(12, res);1381 // Check that vsnprintf_l() works fine with Asan.1382 res = vsnprintf_l_wrapper(buff, 5, SANITIZER_GET_C_LOCALE, "%s",1383 "vsnprintf_l()");1384 EXPECT_EQ(13, res);1385 1386 EXPECT_DEATH(1387 snprintf_l(buff, 10, SANITIZER_GET_C_LOCALE, "%s", "snprintf_l()"),1388 "AddressSanitizer: stack-buffer-overflow");1389 EXPECT_DEATH(vsnprintf_l_wrapper(buff, 10, SANITIZER_GET_C_LOCALE, "%s",1390 "vsnprintf_l()"),1391 "AddressSanitizer: stack-buffer-overflow");1392}1393#endif1394