diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp --- a/clang/lib/CodeGen/BackendUtil.cpp +++ b/clang/lib/CodeGen/BackendUtil.cpp @@ -673,6 +673,16 @@ addSanitizerCoveragePass); } + // Move this here, so DFSan runs before ASan. + // Also change conditional, so DFSan's instrumentation pass runs when ASan + // is enabled. + if (LangOpts.Sanitize.has(SanitizerKind::Address)) { + PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, + addDataFlowSanitizerPass); + PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, + addDataFlowSanitizerPass); + } + if (LangOpts.Sanitize.has(SanitizerKind::Address)) { PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, addAddressSanitizerPasses); @@ -722,13 +732,6 @@ addThreadSanitizerPass); } - if (LangOpts.Sanitize.has(SanitizerKind::DataFlow)) { - PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast, - addDataFlowSanitizerPass); - PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0, - addDataFlowSanitizerPass); - } - // Set up the per-function pass manager. FPM.add(new TargetLibraryInfoWrapperPass(*TLII)); if (CodeGenOpts.VerifyModule) diff --git a/compiler-rt/lib/asan/asan_globals.cpp b/compiler-rt/lib/asan/asan_globals.cpp --- a/compiler-rt/lib/asan/asan_globals.cpp +++ b/compiler-rt/lib/asan/asan_globals.cpp @@ -26,6 +26,28 @@ #include "sanitizer_common/sanitizer_stackdepot.h" #include "sanitizer_common/sanitizer_symbolizer.h" +typedef __sanitizer::u16 dfsan_label; + +SANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL dfsan_label __dfsan_retval_tls; +SANITIZER_INTERFACE_ATTRIBUTE THREADLOCAL dfsan_label __dfsan_arg_tls[64]; + +extern "C" SANITIZER_INTERFACE_ATTRIBUTE dfsan_label +__dfsan_union(dfsan_label l1, dfsan_label l2) { + // if (flags().fast16labels) + return l1 | l2; +} + +extern "C" SANITIZER_INTERFACE_ATTRIBUTE dfsan_label +__dfsan_union_load(const dfsan_label *ls, uptr n) { + dfsan_label label = ls[0]; + for (uptr i = 1; i != n; ++i) { + dfsan_label next_label = ls[i]; + if (label != next_label) + label = __dfsan_union(label, next_label); + } + return label; +} + namespace __asan { typedef __asan_global Global; diff --git a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp --- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp @@ -1058,6 +1058,12 @@ getArgTLSPtr(), 0, Idx); } +static void SetNoSanitizeMetadata(Instruction *I) { + I->setMetadata( + I->getParent()->getParent()->getParent()->getMDKindID("nosanitize"), + MDNode::get(I->getContext(), None)); +} + Value *DFSanFunction::getShadow(Value *V) { if (!isa(V) && !isa(V)) return DFS.ZeroShadow; @@ -1073,8 +1079,10 @@ DFS.ArgTLS ? &*F->getEntryBlock().begin() : cast(ArgTLSPtr)->getNextNode(); IRBuilder<> IRB(ArgTLSPos); - Shadow = + LoadInst *LI = IRB.CreateLoad(DFS.ShadowTy, getArgTLS(A->getArgNo(), ArgTLSPos)); + SetNoSanitizeMetadata(LI); + Shadow = LI; break; } case DataFlowSanitizer::IA_Args: { @@ -1105,9 +1113,11 @@ assert(Addr != RetvalTLS && "Reinstrumenting?"); IRBuilder<> IRB(Pos); Value *ShadowPtrMaskValue; - if (DFSanRuntimeShadowMask) - ShadowPtrMaskValue = IRB.CreateLoad(IntptrTy, ExternalShadowMask); - else + if (DFSanRuntimeShadowMask) { + LoadInst *LI = IRB.CreateLoad(IntptrTy, ExternalShadowMask); + SetNoSanitizeMetadata(LI); + ShadowPtrMaskValue = LI; + } else ShadowPtrMaskValue = ShadowPtrMask; return IRB.CreateIntToPtr( IRB.CreateMul( @@ -1225,7 +1235,9 @@ const auto i = AllocaShadowMap.find(AI); if (i != AllocaShadowMap.end()) { IRBuilder<> IRB(Pos); - return IRB.CreateLoad(DFS.ShadowTy, i->second); + LoadInst *LI = IRB.CreateLoad(DFS.ShadowTy, i->second); + SetNoSanitizeMetadata(LI); + return LI; } } @@ -1366,7 +1378,8 @@ const auto i = AllocaShadowMap.find(AI); if (i != AllocaShadowMap.end()) { IRBuilder<> IRB(Pos); - IRB.CreateStore(Shadow, i->second); + StoreInst *SI = IRB.CreateStore(Shadow, i->second); + SetNoSanitizeMetadata(SI); return; } } @@ -1559,7 +1572,8 @@ case DataFlowSanitizer::IA_TLS: { Value *S = DFSF.getShadow(RI.getReturnValue()); IRBuilder<> IRB(&RI); - IRB.CreateStore(S, DFSF.getRetvalTLS()); + StoreInst *SI = IRB.CreateStore(S, DFSF.getRetvalTLS()); + SetNoSanitizeMetadata(SI); break; } case DataFlowSanitizer::IA_Args: { @@ -1666,7 +1680,8 @@ for (unsigned n = 0; i != CB.arg_end(); ++i, ++n) { auto LabelVAPtr = IRB.CreateStructGEP(LabelVATy, LabelVAAlloca, n); - IRB.CreateStore(DFSF.getShadow(*i), LabelVAPtr); + StoreInst *SI = IRB.CreateStore(DFSF.getShadow(*i), LabelVAPtr); + SetNoSanitizeMetadata(SI); } Args.push_back(IRB.CreateStructGEP(LabelVATy, LabelVAAlloca, 0)); @@ -1702,6 +1717,7 @@ if (!FT->getReturnType()->isVoidTy()) { LoadInst *LabelLoad = IRB.CreateLoad(DFSF.DFS.ShadowTy, DFSF.LabelReturnAlloca); + SetNoSanitizeMetadata(LabelLoad); DFSF.setShadow(CustomCI, LabelLoad); } @@ -1716,8 +1732,9 @@ FunctionType *FT = CB.getFunctionType(); if (DFSF.DFS.getInstrumentedABI() == DataFlowSanitizer::IA_TLS) { for (unsigned i = 0, n = FT->getNumParams(); i != n; ++i) { - IRB.CreateStore(DFSF.getShadow(CB.getArgOperand(i)), - DFSF.getArgTLS(i, &CB)); + StoreInst *SI = IRB.CreateStore(DFSF.getShadow(CB.getArgOperand(i)), + DFSF.getArgTLS(i, &CB)); + SetNoSanitizeMetadata(SI); } } @@ -1739,6 +1756,7 @@ if (DFSF.DFS.getInstrumentedABI() == DataFlowSanitizer::IA_TLS) { IRBuilder<> NextIRB(Next); LoadInst *LI = NextIRB.CreateLoad(DFSF.DFS.ShadowTy, DFSF.getRetvalTLS()); + SetNoSanitizeMetadata(LI); DFSF.SkipInsts.insert(LI); DFSF.setShadow(&CB, LI); DFSF.NonZeroChecks.push_back(LI); @@ -1769,9 +1787,10 @@ "", &DFSF.F->getEntryBlock().front()); Args.push_back(IRB.CreateConstGEP2_32(VarArgArrayTy, VarArgShadow, 0, 0)); for (unsigned n = 0; i != E; ++i, ++n) { - IRB.CreateStore( + StoreInst *SI = IRB.CreateStore( DFSF.getShadow(*i), IRB.CreateConstGEP2_32(VarArgArrayTy, VarArgShadow, 0, n)); + SetNoSanitizeMetadata(SI); Args.push_back(*i); } } diff --git a/load.c b/load.c new file mode 100644 --- /dev/null +++ b/load.c @@ -0,0 +1,6 @@ +int load(int *p) { return *p; } + +int main() { + int i = 10; + load(&i); +}