104 lines · c
1// RUN: %clang_hwasan -O1 %s -o %t2// RUN: %env_hwasan_opts=stack_history_size=1 not %run %t 2>&1 | FileCheck %s --check-prefix=D13// RUN: %env_hwasan_opts=stack_history_size=2 not %run %t 2>&1 | FileCheck %s --check-prefix=D24// RUN: %env_hwasan_opts=stack_history_size=3 not %run %t 2>&1 | FileCheck %s --check-prefix=D35// RUN: %env_hwasan_opts=stack_history_size=5 not %run %t 2>&1 | FileCheck %s --check-prefix=D56// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=DEFAULT7 8// Run the same tests as above, but using the __hwasan_add_frame_record libcall.9// The output should be the exact same.10// RUN: %clang_hwasan -O1 %s -o %t -mllvm -hwasan-record-stack-history=libcall11// RUN: %env_hwasan_opts=stack_history_size=1 not %run %t 2>&1 | FileCheck %s --check-prefix=D112// RUN: %env_hwasan_opts=stack_history_size=2 not %run %t 2>&1 | FileCheck %s --check-prefix=D213// RUN: %env_hwasan_opts=stack_history_size=3 not %run %t 2>&1 | FileCheck %s --check-prefix=D314// RUN: %env_hwasan_opts=stack_history_size=5 not %run %t 2>&1 | FileCheck %s --check-prefix=D515// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=DEFAULT16 17// Stack histories are currently not recorded on x86.18// XFAIL: target=x86_64{{.*}}19 20#include <assert.h>21#include <sanitizer/hwasan_interface.h>22#include <stdlib.h>23 24// At least -O1 is needed for this function to not have a stack frame on25// AArch64.26void USE(void *x) { // pretend_to_do_something(void *x)27 __asm__ __volatile__("" : : "r" (x) : "memory");28}29 30volatile int four = 4;31 32__attribute__((noinline)) void OOB() {33 int x[4];34 int y[4];35 36 // Tags for stack-allocated variables can occasionally be zero, resulting in37 // a false negative for this test. The tag allocation algorithm is not easy38 // to fix, hence we work around it: if the tag is zero, we use the39 // neighboring variable instead, which must have a different (hence non-zero)40 // tag.41 if (__hwasan_tag_pointer(x, 0) == x) {42 assert(__hwasan_tag_pointer(y, 0) != y);43 y[four] = 0;44 } else {45 x[four] = 0;46 }47 USE(&x[0]);48 USE(&y[0]);49}50__attribute__((noinline)) void FUNC1() { int x; USE(&x); OOB(); }51__attribute__((noinline)) void FUNC2() { int x; USE(&x); FUNC1(); }52__attribute__((noinline)) void FUNC3() { int x; USE(&x); FUNC2(); }53__attribute__((noinline)) void FUNC4() { int x; USE(&x); FUNC3(); }54__attribute__((noinline)) void FUNC5() { int x; USE(&x); FUNC4(); }55__attribute__((noinline)) void FUNC6() { int x; USE(&x); FUNC5(); }56__attribute__((noinline)) void FUNC7() { int x; USE(&x); FUNC6(); }57__attribute__((noinline)) void FUNC8() { int x; USE(&x); FUNC7(); }58__attribute__((noinline)) void FUNC9() { int x; USE(&x); FUNC8(); }59__attribute__((noinline)) void FUNC10() { int x; USE(&x); FUNC9(); }60 61int main() { FUNC10(); }62 63// D1: Previously allocated frames64// D1: in OOB65// D1-NOT: in FUNC66// D1: Memory tags around the buggy address67 68// D2: Previously allocated frames69// D2: in OOB70// D2: in FUNC171// D2-NOT: in FUNC72// D2: Memory tags around the buggy address73 74// D3: Previously allocated frames75// D3: in OOB76// D3: in FUNC177// D3: in FUNC278// D3-NOT: in FUNC79// D3: Memory tags around the buggy address80 81// D5: Previously allocated frames82// D5: in OOB83// D5: in FUNC184// D5: in FUNC285// D5: in FUNC386// D5: in FUNC487// D5-NOT: in FUNC88// D5: Memory tags around the buggy address89 90// DEFAULT: Previously allocated frames91// DEFAULT: in OOB92// DEFAULT: in FUNC193// DEFAULT: in FUNC294// DEFAULT: in FUNC395// DEFAULT: in FUNC496// DEFAULT: in FUNC597// DEFAULT: in FUNC698// DEFAULT: in FUNC799// DEFAULT: in FUNC8100// DEFAULT: in FUNC9101// DEFAULT: in FUNC10102// DEFAULT-NOT: in FUNC103// DEFAULT: Memory tags around the buggy address104