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
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#else
35/* 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#endif
52

source code of compiler-rt/test/asan/TestCases/Linux/longjmp_chk.c