1 // Verify that use of longjmp() in a _FORTIFY_SOURCE'd library (without ASAN) 2 // is correctly intercepted such that the stack is unpoisoned. 3 // Note: it is essential that the external library is not built with ASAN, 4 // otherwise it would be able to unpoison the stack before use. 5 // 6 // RUN: %clang -DIS_LIBRARY -D_FORTIFY_SOURCE=2 -O2 %s -c -o %t.o 7 // RUN: %clang_asan -O2 %s %t.o -o %t 8 // RUN: %run %t 9 10 #ifdef IS_LIBRARY 11 /* the library */ 12 #include <setjmp.h> 13 #include <assert.h> 14 #include <sanitizer/asan_interface.h> 15 16 static jmp_buf jenv; 17 external_callme(void (* callback)(void))18void external_callme(void (*callback)(void)) { 19 if (setjmp(jenv) == 0) { 20 callback(); 21 } 22 } 23 external_longjmp(char * msg)24void external_longjmp(char *msg) { 25 longjmp(jenv, 1); 26 } 27 external_check_stack(void)28void external_check_stack(void) { 29 char buf[256] = ""; 30 for (int i = 0; i < 256; i++) { 31 assert(!__asan_address_is_poisoned(buf + i)); 32 } 33 } 34 #else 35 /* main program */ 36 extern void external_callme(void (*callback)(void)); 37 extern void external_longjmp(char *msg); 38 extern void external_check_stack(void); 39 callback(void)40static void callback(void) { 41 char msg[16]; /* Note: this triggers addition of a redzone. */ 42 /* Note: msg is passed to prevent compiler optimization from removing it. */ 43 external_longjmp(msg); 44 } 45 main()46int main() { 47 external_callme(callback); 48 external_check_stack(); 49 return 0; 50 } 51 #endif 52