| 1 | // Test how stack frames are reported (not fully implemented yet). |
| 2 | // RUN: %clang_hwasan %s -o %t |
| 3 | // RUN: not %run %t 3 2 -1 2>&1 | FileCheck %s --check-prefix=R321 |
| 4 | // REQUIRES: pointer-tagging |
| 5 | |
| 6 | #include <stdint.h> |
| 7 | #include <stdlib.h> |
| 8 | void USE(void *x) { // pretend_to_do_something(void *x) |
| 9 | __asm__ __volatile__("" : : "r" (x) : "memory" ); |
| 10 | } |
| 11 | void USE2(void *a, void *b) { USE(x: a); USE(x: b); } |
| 12 | void USE4(void *a, void *b, void *c, void *d) { USE2(a, b); USE2(a: c, b: d); } |
| 13 | |
| 14 | void BAR(int depth, int err_depth, int offset); |
| 15 | |
| 16 | uint64_t *leaked_ptr; |
| 17 | |
| 18 | void FOO(int depth, int err_depth, int offset) { |
| 19 | uint8_t v1; |
| 20 | uint16_t v2; |
| 21 | uint32_t v4; |
| 22 | uint64_t v8; |
| 23 | uint64_t v16[2]; |
| 24 | uint64_t v32[4]; |
| 25 | uint64_t v48[3]; |
| 26 | USE4(a: &v1, b: &v2, c: &v4, d: &v8); USE4(a: &v16, b: &v32, c: &v48, d: 0); |
| 27 | leaked_ptr = &v16[0]; |
| 28 | if (depth) |
| 29 | BAR(depth: depth - 1, err_depth, offset); |
| 30 | |
| 31 | if (err_depth == depth) |
| 32 | v16[offset] = 0; // maybe OOB. |
| 33 | if (err_depth == -depth) |
| 34 | leaked_ptr[offset] = 0; // maybe UAR. |
| 35 | USE(x: &v16); |
| 36 | } |
| 37 | |
| 38 | void BAR(int depth, int err_depth, int offset) { |
| 39 | uint64_t x16[2]; |
| 40 | uint64_t x32[4]; |
| 41 | USE2(a: &x16, b: &x32); |
| 42 | leaked_ptr = &x16[0]; |
| 43 | if (depth) |
| 44 | FOO(depth: depth - 1, err_depth, offset); |
| 45 | if (err_depth == depth) |
| 46 | x16[offset] = 0; // maybe OOB |
| 47 | if (err_depth == -depth) |
| 48 | leaked_ptr[offset] = 0; // maybe UAR |
| 49 | USE(x: &x16); |
| 50 | } |
| 51 | |
| 52 | |
| 53 | int main(int argc, char **argv) { |
| 54 | if (argc != 4) return -1; |
| 55 | int depth = atoi(nptr: argv[1]); |
| 56 | int err_depth = atoi(nptr: argv[2]); |
| 57 | int offset = atoi(nptr: argv[3]); |
| 58 | FOO(depth, err_depth, offset); |
| 59 | return 0; |
| 60 | } |
| 61 | |
| 62 | // R321: HWAddressSanitizer: tag-mismatch |
| 63 | // R321-NEXT: WRITE of size 8 |
| 64 | // R321: in BAR |
| 65 | // R321-NEXT: in FOO |
| 66 | // R321-NEXT: in main |
| 67 | // R321: is located in stack of thread T0 |
| 68 | |