112 lines · c
1// RUN: %clang_dfsan -fno-sanitize=dataflow -O2 -fPIE -DCALLBACKS -c %s -o %t-callbacks.o2// RUN: %clang_dfsan -fsanitize-ignorelist=%S/Inputs/flags_abilist.txt -O2 -mllvm -dfsan-conditional-callbacks %s %t-callbacks.o -o %t3// RUN: %run %t FooBarBaz 2>&1 | FileCheck %s4//5// RUN: %clang_dfsan -fno-sanitize=dataflow -O2 -fPIE -DCALLBACKS -DORIGINS -c %s -o %t-callbacks-orig.o6// RUN: %clang_dfsan -fsanitize-ignorelist=%S/Inputs/flags_abilist.txt -O2 -mllvm -dfsan-conditional-callbacks -mllvm -dfsan-track-origins=1 -DORIGINS %s %t-callbacks-orig.o -o %t-orig7// RUN: %run %t-orig FooBarBaz 2>&1 | FileCheck %s8 9// Tests that callbacks are inserted for conditionals when10// -dfsan-conditional-callbacks is specified.11 12#include <assert.h>13#include <sanitizer/dfsan_interface.h>14#include <stdio.h>15#include <string.h>16 17#ifdef CALLBACKS18// Compile this code without DFSan to avoid recursive instrumentation.19 20extern dfsan_label LabelI;21extern dfsan_label LabelJ;22extern dfsan_label LabelIJ;23 24void my_dfsan_conditional_callback(dfsan_label Label, dfsan_origin Origin) {25 assert(Label != 0);26#ifdef ORIGINS27 assert(Origin != 0);28#else29 assert(Origin == 0);30#endif31 32 static int Count = 0;33 switch (Count++) {34 case 0:35 assert(Label == LabelI);36 break;37 case 1:38 assert(Label == LabelJ);39 break;40 case 2:41 assert(Label == LabelIJ);42 break;43 default:44 break;45 }46 47 fprintf(stderr, "Label %u used as condition\n", Label);48}49 50#else51// Compile this code with DFSan and -dfsan-conditional-callbacks to insert the52// callbacks.53 54dfsan_label LabelI;55dfsan_label LabelJ;56dfsan_label LabelIJ;57 58extern void my_dfsan_conditional_callback(dfsan_label Label,59 dfsan_origin Origin);60 61int main(int Argc, char *Argv[]) {62 assert(Argc == 2);63 64 dfsan_set_conditional_callback(my_dfsan_conditional_callback);65 66 int result = 0;67 // Make these not look like constants, otherwise the branch we're expecting68 // may be optimized out.69 int DataI = (Argv[0][0] != 0) ? 1 : 0;70 int DataJ = (Argv[1][0] != 0) ? 2 : 0;71 LabelI = 1;72 dfsan_set_label(LabelI, &DataI, sizeof(DataI));73 LabelJ = 2;74 dfsan_set_label(LabelJ, &DataJ, sizeof(DataJ));75 LabelIJ = dfsan_union(LabelI, LabelJ);76 77 assert(dfsan_get_label(DataI) == LabelI);78 79 // CHECK: Label 1 used as condition80 if (DataI) {81 result = 42;82 }83 84 fprintf(stderr, "Result is %d\n", result);85 assert(dfsan_get_label(DataJ) == LabelJ);86 87 // CHECK: Label 2 used as condition88 switch (DataJ) {89 case 1:90 result += 10000;91 break;92 case 2:93 result += 4200;94 break;95 default:96 break;97 }98 99 int tainted_cond = ((DataI * DataJ) != 1);100 fprintf(stderr, "Result is %d\n", result);101 assert(dfsan_get_label(tainted_cond) == LabelIJ);102 103 // CHECK: Label 3 used as condition104 result = tainted_cond ? result + 420000 : 9;105 106 fprintf(stderr, "Result is %d\n", result);107 assert(result == 424242);108 return 0;109}110 111#endif // #ifdef CALLBACKS112