[llvm] r222991 - [asan] Change dynamic alloca instrumentation to only consider allocas that are dominating all exits from function.
Yury Gribov
y.gribov at samsung.com
Mon Dec 1 00:47:59 PST 2014
Author: ygribov
Date: Mon Dec 1 02:47:58 2014
New Revision: 222991
URL: http://llvm.org/viewvc/llvm-project?rev=222991&view=rev
Log:
[asan] Change dynamic alloca instrumentation to only consider allocas that are dominating all exits from function.
Reviewed in http://reviews.llvm.org/D6412
Added:
llvm/trunk/test/Instrumentation/AddressSanitizer/undecidable-dynamic-alloca-1.ll
Modified:
llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp
Modified: llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp?rev=222991&r1=222990&r2=222991&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp (original)
+++ llvm/trunk/lib/Transforms/Instrumentation/AddressSanitizer.cpp Mon Dec 1 02:47:58 2014
@@ -27,6 +27,7 @@
#include "llvm/IR/CallSite.h"
#include "llvm/IR/DIBuilder.h"
#include "llvm/IR/DataLayout.h"
+#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/IRBuilder.h"
#include "llvm/IR/InlineAsm.h"
@@ -348,10 +349,15 @@ static size_t RedzoneSizeForScale(int Ma
/// AddressSanitizer: instrument the code in module to find memory bugs.
struct AddressSanitizer : public FunctionPass {
- AddressSanitizer() : FunctionPass(ID) {}
+ AddressSanitizer() : FunctionPass(ID) {
+ initializeAddressSanitizerPass(*PassRegistry::getPassRegistry());
+ }
const char *getPassName() const override {
return "AddressSanitizerFunctionPass";
}
+ void getAnalysisUsage(AnalysisUsage &AU) const override {
+ AU.addRequired<DominatorTreeWrapperPass>();
+ }
void instrumentMop(Instruction *I, bool UseCalls);
void instrumentPointerComparisonOrSubtraction(Instruction *I);
void instrumentAddress(Instruction *OrigIns, Instruction *InsertBefore,
@@ -369,6 +375,8 @@ struct AddressSanitizer : public Functio
bool doInitialization(Module &M) override;
static char ID; // Pass identification, replacement for typeid
+ DominatorTree &getDominatorTree() const { return *DT; }
+
private:
void initializeCallbacks(Module &M);
@@ -380,6 +388,7 @@ struct AddressSanitizer : public Functio
int LongSize;
Type *IntptrTy;
ShadowMapping Mapping;
+ DominatorTree *DT;
Function *AsanCtorFunction;
Function *AsanInitFunction;
Function *AsanHandleNoReturnFunc;
@@ -471,10 +480,11 @@ struct FunctionStackPoisoner : public In
AllocaInst *AI;
Value *LeftRzAddr;
Value *RightRzAddr;
+ bool Poison;
explicit DynamicAllocaCall(AllocaInst *AI,
Value *LeftRzAddr = nullptr,
Value *RightRzAddr = nullptr)
- : AI(AI), LeftRzAddr(LeftRzAddr), RightRzAddr(RightRzAddr)
+ : AI(AI), LeftRzAddr(LeftRzAddr), RightRzAddr(RightRzAddr), Poison(true)
{}
};
SmallVector<DynamicAllocaCall, 1> DynamicAllocaVec;
@@ -520,6 +530,8 @@ struct FunctionStackPoisoner : public In
// Unpoison dynamic allocas redzones.
void unpoisonDynamicAlloca(DynamicAllocaCall &AllocaCall) {
+ if (!AllocaCall.Poison)
+ return;
for (auto Ret : RetVec) {
IRBuilder<> IRBRet(Ret);
PointerType *Int32PtrTy = PointerType::getUnqual(IRBRet.getInt32Ty());
@@ -605,6 +617,14 @@ struct FunctionStackPoisoner : public In
// ---------------------- Helpers.
void initializeCallbacks(Module &M);
+ bool doesDominateAllExits(const Instruction *I) const {
+ for (auto Ret : RetVec) {
+ if (!ASan.getDominatorTree().dominates(I, Ret))
+ return false;
+ }
+ return true;
+ }
+
bool isDynamicAlloca(AllocaInst &AI) const {
return AI.isArrayAllocation() || !AI.isStaticAlloca();
}
@@ -634,7 +654,11 @@ struct FunctionStackPoisoner : public In
} // namespace
char AddressSanitizer::ID = 0;
-INITIALIZE_PASS(AddressSanitizer, "asan",
+INITIALIZE_PASS_BEGIN(AddressSanitizer, "asan",
+ "AddressSanitizer: detects use-after-free and out-of-bounds bugs.",
+ false, false)
+INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
+INITIALIZE_PASS_END(AddressSanitizer, "asan",
"AddressSanitizer: detects use-after-free and out-of-bounds bugs.",
false, false)
FunctionPass *llvm::createAddressSanitizerFunctionPass() {
@@ -1354,6 +1378,8 @@ bool AddressSanitizer::runOnFunction(Fun
DEBUG(dbgs() << "ASAN instrumenting:\n" << F << "\n");
initializeCallbacks(*F.getParent());
+ DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
+
// If needed, insert __asan_init before checking for SanitizeAddress attr.
maybeInsertAsanInitAtFunctionEntry(F);
@@ -1825,6 +1851,12 @@ Value *FunctionStackPoisoner::computePar
void FunctionStackPoisoner::handleDynamicAllocaCall(
DynamicAllocaCall &AllocaCall) {
AllocaInst *AI = AllocaCall.AI;
+ if (!doesDominateAllExits(AI)) {
+ // We do not yet handle complex allocas
+ AllocaCall.Poison = false;
+ return;
+ }
+
IRBuilder<> IRB(AI);
PointerType *Int32PtrTy = PointerType::getUnqual(IRB.getInt32Ty());
Added: llvm/trunk/test/Instrumentation/AddressSanitizer/undecidable-dynamic-alloca-1.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Instrumentation/AddressSanitizer/undecidable-dynamic-alloca-1.ll?rev=222991&view=auto
==============================================================================
--- llvm/trunk/test/Instrumentation/AddressSanitizer/undecidable-dynamic-alloca-1.ll (added)
+++ llvm/trunk/test/Instrumentation/AddressSanitizer/undecidable-dynamic-alloca-1.ll Mon Dec 1 02:47:58 2014
@@ -0,0 +1,23 @@
+; Test that undecidable dynamic allocas are skipped by ASan.
+
+; RUN: opt < %s -asan -asan-module -asan-instrument-allocas=1 -S | FileCheck %s
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @g(i64 %n) sanitize_address {
+entry:
+ %cmp = icmp sgt i64 %n, 100
+ br i1 %cmp, label %do_alloca, label %done
+
+do_alloca:
+; CHECK-NOT: store i32 -892679478
+ %0 = alloca i8, i64 %n, align 1
+ call void @f(i8* %0)
+ br label %done
+
+done:
+ ret void
+}
+
+declare void @f(i8*)
+
More information about the llvm-commits
mailing list