16a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// RUN: %clangxx_asan %s -pthread -o %t 22d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 32d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK0 486277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// RUN: %clangxx_asan -O3 %s -pthread -o %t 586277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK1 686277eb844c4983c81de62d7c050e92fe7155788Stephen Hines// RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK0 76a211c5814e25d6745a5058cc0e499e5235d3821Stephen Hines// REQUIRES: stable-runtime 82d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 92d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include <assert.h> 102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include <stdio.h> 112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include <pthread.h> 122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines#include <sanitizer/asan_interface.h> 132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesstatic const int kNumThreads = 2; 1586277eb844c4983c81de62d7c050e92fe7155788Stephen Hinesstatic const int kLeftRedzoneSize = sizeof(void *) * 4; 162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesvoid *Thread(void *unused) { 182d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines void *fake_stack = __asan_get_current_fake_stack(); 192d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines char var[15]; 202d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines if (fake_stack) { 212d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines fprintf(stderr, "fake stack found: %p; var: %p\n", fake_stack, var); 222d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // CHECK1: fake stack found 232d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // CHECK1: fake stack found 242d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines void *beg, *end; 252d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines void *real_stack = 262d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines __asan_addr_is_in_fake_stack(fake_stack, &var[0], &beg, &end); 272d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines assert(real_stack); 282d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines assert((char*)beg <= (char*)&var[0]); 292d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines assert((char*)end > (char*)&var[0]); 3086277eb844c4983c81de62d7c050e92fe7155788Stephen Hines for (int i = -kLeftRedzoneSize; i < 15; i++) { 312d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines void *beg1, *end1; 322d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines char *ptr = &var[0] + i; 332d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines void *real_stack1 = 342d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines __asan_addr_is_in_fake_stack(fake_stack, ptr, &beg1, &end1); 352d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines assert(real_stack == real_stack1); 362d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines assert(beg == beg1); 372d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines assert(end == end1); 382d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } 392d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } else { 402d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines fprintf(stderr, "no fake stack\n"); 412d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // CHECK0: no fake stack 422d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines // CHECK0: no fake stack 432d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines } 442d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return NULL; 452d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 462d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines 472d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hinesint main(int argc, char **argv) { 482d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines pthread_t t[kNumThreads]; 492d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines for (int i = 0; i < kNumThreads; i++) 502d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines pthread_create(&t[i], 0, Thread, 0); 512d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines for (int i = 0; i < kNumThreads; i++) 522d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines pthread_join(t[i], 0); 532d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines return 0; 542d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines} 55