deep-recursion.c
2.42 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
// RUN: %clang_hwasan -O1 %s -o %t
// RUN: %env_hwasan_opts=stack_history_size=1 not %run %t 2>&1 | FileCheck %s --check-prefix=D1
// RUN: %env_hwasan_opts=stack_history_size=2 not %run %t 2>&1 | FileCheck %s --check-prefix=D2
// RUN: %env_hwasan_opts=stack_history_size=3 not %run %t 2>&1 | FileCheck %s --check-prefix=D3
// RUN: %env_hwasan_opts=stack_history_size=5 not %run %t 2>&1 | FileCheck %s --check-prefix=D5
// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=DEFAULT
// REQUIRES: stable-runtime
#include <stdlib.h>
// At least -O1 is needed for this function to not have a stack frame on
// AArch64.
void USE(void *x) { // pretend_to_do_something(void *x)
__asm__ __volatile__("" : : "r" (x) : "memory");
}
volatile int four = 4;
__attribute__((noinline)) void OOB() { int x[4]; x[four] = 0; USE(&x[0]); }
__attribute__((noinline)) void FUNC1() { int x; USE(&x); OOB(); }
__attribute__((noinline)) void FUNC2() { int x; USE(&x); FUNC1(); }
__attribute__((noinline)) void FUNC3() { int x; USE(&x); FUNC2(); }
__attribute__((noinline)) void FUNC4() { int x; USE(&x); FUNC3(); }
__attribute__((noinline)) void FUNC5() { int x; USE(&x); FUNC4(); }
__attribute__((noinline)) void FUNC6() { int x; USE(&x); FUNC5(); }
__attribute__((noinline)) void FUNC7() { int x; USE(&x); FUNC6(); }
__attribute__((noinline)) void FUNC8() { int x; USE(&x); FUNC7(); }
__attribute__((noinline)) void FUNC9() { int x; USE(&x); FUNC8(); }
__attribute__((noinline)) void FUNC10() { int x; USE(&x); FUNC9(); }
int main() { FUNC10(); }
// D1: Previously allocated frames
// D1: in OOB
// D1-NOT: in FUNC
// D1: Memory tags around the buggy address
// D2: Previously allocated frames
// D2: in OOB
// D2: in FUNC1
// D2-NOT: in FUNC
// D2: Memory tags around the buggy address
// D3: Previously allocated frames
// D3: in OOB
// D3: in FUNC1
// D3: in FUNC2
// D3-NOT: in FUNC
// D3: Memory tags around the buggy address
// D5: Previously allocated frames
// D5: in OOB
// D5: in FUNC1
// D5: in FUNC2
// D5: in FUNC3
// D5: in FUNC4
// D5-NOT: in FUNC
// D5: Memory tags around the buggy address
// DEFAULT: Previously allocated frames
// DEFAULT: in OOB
// DEFAULT: in FUNC1
// DEFAULT: in FUNC2
// DEFAULT: in FUNC3
// DEFAULT: in FUNC4
// DEFAULT: in FUNC5
// DEFAULT: in FUNC6
// DEFAULT: in FUNC7
// DEFAULT: in FUNC8
// DEFAULT: in FUNC9
// DEFAULT: in FUNC10
// DEFAULT-NOT: in FUNC
// DEFAULT: Memory tags around the buggy address