1 // RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 %s -o %t && \ 2 // RUN: %run %t >%t.out 2>&1 3 // RUN: FileCheck %s < %t.out 4 // 5 // RUN: %clang_dfsan -gmlt -mllvm -dfsan-track-origins=1 -mllvm -dfsan-instrument-with-call-threshold=0 %s -o %t && \ 6 // RUN: %run %t >%t.out 2>&1 7 // RUN: FileCheck %s < %t.out 8 // 9 // REQUIRES: x86_64-target-arch 10 11 #include <sanitizer/dfsan_interface.h> 12 #include <stdio.h> 13 #include <string.h> 14 15 #define NOINLINE __attribute__((noinline)) 16 17 NOINLINE int foo(int a, int b) { return a + b; } 18 19 NOINLINE void bar(int depth, void *addr, int size) { 20 if (depth) { 21 bar(depth - 1, addr, size); 22 } else { 23 dfsan_set_label(1, addr, size); 24 } 25 } 26 27 NOINLINE void baz(int depth, void *addr, int size) { 28 bar(depth, addr, size); 29 } 30 31 int main(int argc, char *argv[]) { 32 int a = 10; 33 int b = 20; 34 baz(8, &a, sizeof(a)); 35 int c = foo(a, b); 36 dfsan_print_origin_trace(&c, NULL); 37 // CHECK: Taint value 0x1 {{.*}} origin tracking () 38 // CHECK: Origin value: {{.*}}, Taint value was stored to memory at 39 // CHECK: #0 {{.*}} in main {{.*}}origin_stack_trace.c:[[@LINE-4]] 40 41 // CHECK: Origin value: {{.*}}, Taint value was created at 42 // CHECK: #0 {{.*}} in bar.dfsan {{.*}}origin_stack_trace.c:[[@LINE-19]] 43 // CHECK-COUNT-8: #{{[0-9]+}} {{.*}} in bar.dfsan {{.*}}origin_stack_trace.c:[[@LINE-22]] 44 // CHECK: #9 {{.*}} in baz.dfsan {{.*}}origin_stack_trace.c:[[@LINE-16]] 45 46 char buf[3000]; 47 size_t length = dfsan_sprint_origin_trace(&c, NULL, buf, sizeof(buf)); 48 49 printf("==OUTPUT==\n\n%s==EOS==\n", buf); 50 // CHECK: ==OUTPUT== 51 // CHECK: Taint value 0x1 {{.*}} origin tracking () 52 // CHECK: Origin value: {{.*}}, Taint value was stored to memory at 53 // CHECK: #0 {{.*}} in main {{.*}}origin_stack_trace.c:[[@LINE-18]] 54 55 // CHECK: Origin value: {{.*}}, Taint value was created at 56 // CHECK: #0 {{.*}} in bar.dfsan {{.*}}origin_stack_trace.c:[[@LINE-33]] 57 // CHECK-COUNT-8: #{{[0-9]+}} {{.*}} in bar.dfsan {{.*}}origin_stack_trace.c:[[@LINE-36]] 58 // CHECK: #9 {{.*}} in baz.dfsan {{.*}}origin_stack_trace.c:[[@LINE-30]] 59 // CHECK: ==EOS== 60 61 char tinybuf[18]; 62 size_t same_length = dfsan_sprint_origin_trace(&c, NULL, tinybuf, sizeof(tinybuf)); 63 64 printf("==TRUNCATED OUTPUT==\n\n%s==EOS==\n", tinybuf); 65 // CHECK: ==TRUNCATED OUTPUT== 66 // CHECK: Taint value 0x1==EOS== 67 68 printf("Returned length: %zu\n", length); 69 printf("Actual length: %zu\n", strlen(buf)); 70 printf("Returned length with truncation: %zu\n", same_length); 71 72 // CHECK: Returned length: [[#LEN:]] 73 // CHECK: Actual length: [[#LEN]] 74 // CHECK: Returned length with truncation: [[#LEN]] 75 76 size_t length_with_desc = dfsan_sprint_origin_trace(&c, "DESCRIPTION", buf, sizeof(buf)); 77 78 printf("==OUTPUT==\n\n%s==EOS==\n", buf); 79 // CHECK: ==OUTPUT== 80 // CHECK: Taint value 0x1 {{.*}} origin tracking (DESCRIPTION) 81 // CHECK: Origin value: {{.*}}, Taint value was stored to memory at 82 // CHECK: #0 {{.*}} in main {{.*}}origin_stack_trace.c:[[@LINE-47]] 83 84 // CHECK: Origin value: {{.*}}, Taint value was created at 85 // CHECK: #0 {{.*}} in bar.dfsan {{.*}}origin_stack_trace.c:[[@LINE-62]] 86 // CHECK-COUNT-8: #{{[0-9]+}} {{.*}} in bar.dfsan {{.*}}origin_stack_trace.c:[[@LINE-65]] 87 // CHECK: #9 {{.*}} in baz.dfsan {{.*}}origin_stack_trace.c:[[@LINE-59]] 88 // CHECK: ==EOS== 89 90 printf("Returned length: %zu\n", length_with_desc); 91 // COMM: Message length is increased by 11: the length of "DESCRIPTION". 92 // CHECK: Returned length: [[#LEN + 11]] 93 94 buf[0] = '\0'; 95 length = dfsan_sprint_origin_trace(&c, NULL, buf, 0); 96 printf("Output=\"%s\"\n", buf); 97 printf("Returned length: %zu\n", length); 98 // CHECK: Output="" 99 // CHECK: Returned length: [[#LEN]] 100 } 101