1 // RUN: export ASAN_OPTIONS=detect_stack_use_after_return=1 2 // RUN: %clangxx_asan -O0 %s -pthread -o %t && not %run %t 2>&1 | FileCheck %s 3 // RUN: %clangxx_asan -O1 %s -pthread -o %t && not %run %t 2>&1 | FileCheck %s 4 // RUN: %clangxx_asan -O2 %s -pthread -o %t && not %run %t 2>&1 | FileCheck %s 5 // RUN: %clangxx_asan -O3 %s -pthread -o %t && not %run %t 2>&1 | FileCheck %s 6 // RUN: env ASAN_OPTIONS=detect_stack_use_after_return=0 %run %t 7 // Regression test for a CHECK failure with small stack size and large frame. 8 // RUN: %clangxx_asan -O3 %s -pthread -o %t -DkSize=10000 -DUseThread -DkStackSize=65536 && not %run %t 2>&1 | FileCheck --check-prefix=THREAD %s 9 // 10 // Test that we can find UAR in a thread other than main: 11 // RUN: %clangxx_asan -DUseThread -O2 %s -pthread -o %t && not %run %t 2>&1 | FileCheck --check-prefix=THREAD %s 12 // 13 // Test the max_uar_stack_size_log/min_uar_stack_size_log flag. 14 // 15 // RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:max_uar_stack_size_log=20:verbosity=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-20 %s 16 // RUN: env ASAN_OPTIONS=$ASAN_OPTIONS:min_uar_stack_size_log=24:max_uar_stack_size_log=24:verbosity=1 not %run %t 2>&1 | FileCheck --check-prefix=CHECK-24 %s 17 18 #include <stdio.h> 19 #include <pthread.h> 20 21 #ifndef kSize 22 # define kSize 1 23 #endif 24 25 #ifndef UseThread 26 # define UseThread 0 27 #endif 28 29 #ifndef kStackSize 30 # define kStackSize 0 31 #endif 32 33 __attribute__((noinline)) 34 char *Ident(char *x) { 35 fprintf(stderr, "1: %p\n", x); 36 return x; 37 } 38 39 __attribute__((noinline)) 40 char *Func1() { 41 char local[kSize]; 42 return Ident(local); 43 } 44 45 __attribute__((noinline)) 46 void Func2(char *x) { 47 fprintf(stderr, "2: %p\n", x); 48 *x = 1; 49 // CHECK: WRITE of size 1 {{.*}} thread T0 50 // CHECK: #0{{.*}}Func2{{.*}}stack-use-after-return.cc:[[@LINE-2]] 51 // CHECK: is located in stack of thread T0 at offset 52 // CHECK: 'local' <== Memory access at offset {{16|32}} is inside this variable 53 // THREAD: WRITE of size 1 {{.*}} thread T{{[1-9]}} 54 // THREAD: #0{{.*}}Func2{{.*}}stack-use-after-return.cc:[[@LINE-6]] 55 // THREAD: is located in stack of thread T{{[1-9]}} at offset 56 // THREAD: 'local' <== Memory access at offset {{16|32}} is inside this variable 57 // CHECK-20: T0: FakeStack created:{{.*}} stack_size_log: 20 58 // CHECK-24: T0: FakeStack created:{{.*}} stack_size_log: 24 59 } 60 61 void *Thread(void *unused) { 62 Func2(Func1()); 63 return NULL; 64 } 65 66 int main(int argc, char **argv) { 67 #if UseThread 68 pthread_attr_t attr; 69 pthread_attr_init(&attr); 70 if (kStackSize > 0) 71 pthread_attr_setstacksize(&attr, kStackSize); 72 pthread_t t; 73 pthread_create(&t, &attr, Thread, 0); 74 pthread_attr_destroy(&attr); 75 pthread_join(t, 0); 76 #else 77 Func2(Func1()); 78 #endif 79 return 0; 80 } 81