52 lines · c
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.o7// RUN: %clang_asan -O2 %s %t.o -o %t8// RUN: %run %t9 10#ifdef IS_LIBRARY11/* the library */12#include <setjmp.h>13#include <assert.h>14#include <sanitizer/asan_interface.h>15 16static jmp_buf jenv;17 18void external_callme(void (*callback)(void)) {19 if (setjmp(jenv) == 0) {20 callback();21 }22}23 24void external_longjmp(char *msg) {25 longjmp(jenv, 1);26}27 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#else35/* main program */36extern void external_callme(void (*callback)(void));37extern void external_longjmp(char *msg);38extern void external_check_stack(void);39 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 46int main() {47 external_callme(callback);48 external_check_stack();49 return 0;50}51#endif52