132 lines · c
1// RUN: %clang_dfsan -fno-sanitize=dataflow -O2 -fPIE -DCALLBACKS -c %s -o %t-callbacks.o2// RUN: %clang_dfsan -O2 -mllvm -dfsan-event-callbacks %s %t-callbacks.o -o %t3// RUN: %run %t FooBarBaz 2>&1 | FileCheck %s4 5// Tests that callbacks are inserted for store events when6// -dfsan-event-callbacks is specified.7 8#include <assert.h>9#include <sanitizer/dfsan_interface.h>10#include <stdio.h>11#include <string.h>12 13#ifdef CALLBACKS14// Compile this code without DFSan to avoid recursive instrumentation.15 16extern dfsan_label LabelI;17extern dfsan_label LabelJ;18extern dfsan_label LabelIJ;19extern dfsan_label LabelArgv;20extern size_t LenArgv;21 22void __dfsan_store_callback(dfsan_label Label) {23 if (!Label)24 return;25 26 static int Count = 0;27 switch (Count++) {28 case 0:29 assert(Label == LabelI);30 break;31 case 1:32 assert(Label == LabelJ);33 break;34 case 2:35 assert(Label == LabelIJ);36 break;37 default:38 assert(0);39 }40 41 fprintf(stderr, "Label %u stored to memory\n", Label);42}43 44void __dfsan_load_callback(dfsan_label Label) {45 if (!Label)46 return;47 48 fprintf(stderr, "Label %u loaded from memory\n", Label);49}50 51void __dfsan_mem_transfer_callback(dfsan_label *Start, size_t Len) {52 assert(Len == LenArgv);53 for (int I = 0; I < Len; ++I) {54 assert(Start[I] == LabelArgv);55 }56 57 fprintf(stderr, "Label %u copied to memory\n", Start[0]);58}59 60void __dfsan_cmp_callback(dfsan_label CombinedLabel) {61 if (!CombinedLabel)62 return;63 64 fprintf(stderr, "Label %u used for branching\n", CombinedLabel);65}66 67#else68// Compile this code with DFSan and -dfsan-event-callbacks to insert the69// callbacks.70 71dfsan_label LabelI;72dfsan_label LabelJ;73dfsan_label LabelIJ;74dfsan_label LabelArgv;75 76size_t LenArgv;77 78int main(int Argc, char *Argv[]) {79 assert(Argc == 2);80 81 int I = 1, J = 2;82 LabelI = 1;83 dfsan_set_label(LabelI, &I, sizeof(I));84 LabelJ = 2;85 dfsan_set_label(LabelJ, &J, sizeof(J));86 LabelIJ = dfsan_union(LabelI, LabelJ);87 88 // CHECK: Label 1 stored to memory89 volatile int Sink = I;90 91 // CHECK: Label 1 loaded from memory92 // CHECK: Label 1 used for branching93 assert(Sink == 1);94 95 // CHECK: Label 2 stored to memory96 Sink = J;97 98 // CHECK: Label 2 loaded from memory99 // CHECK: Label 2 used for branching100 assert(Sink == 2);101 102 // CHECK: Label 2 loaded from memory103 // CHECK: Label 3 stored to memory104 Sink += I;105 106 // CHECK: Label 3 loaded from memory107 // CHECK: Label 3 used for branching108 assert(Sink == 3);109 110 // CHECK: Label 3 used for branching111 assert(I != J);112 113 LenArgv = strlen(Argv[1]);114 LabelArgv = 4;115 dfsan_set_label(LabelArgv, Argv[1], LenArgv);116 117 char Buf[64];118 assert(LenArgv < sizeof(Buf) - 1);119 120 // CHECK: Label 4 copied to memory121 void *volatile SinkPtr = Buf;122 memcpy(SinkPtr, Argv[1], LenArgv);123 124 // CHECK: Label 4 copied to memory125 SinkPtr = &Buf[1];126 memmove(SinkPtr, Buf, LenArgv);127 128 return 0;129}130 131#endif // #ifdef CALLBACKS132