From: Kuba Brecka Date: Mon, 27 Jun 2016 15:57:08 +0000 (+0000) Subject: [asan] fix false dynamic-stack-buffer-overflow report with constantly-sized dynamic... X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=b41eaf777832fe7a8de763528c3b0662badd389d;p=llvm [asan] fix false dynamic-stack-buffer-overflow report with constantly-sized dynamic allocas, LLVM part See the bug report at https://github.com/google/sanitizers/issues/691. When a dynamic alloca has a constant size, ASan instrumentation will treat it as a regular dynamic alloca (insert calls to poison and unpoison), but the backend will turn it into a regular stack variable. The poisoning/unpoisoning is then broken. This patch will treat such allocas as static. Differential Revision: http://reviews.llvm.org/D21509 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@273888 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/lib/Transforms/Instrumentation/AddressSanitizer.cpp index 736adeccb58..451f497b968 100644 --- a/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -454,19 +454,20 @@ struct AddressSanitizer : public FunctionPass { AU.addRequired(); } uint64_t getAllocaSizeInBytes(AllocaInst *AI) const { + uint64_t ArraySize = 1; + if (AI->isArrayAllocation()) { + ConstantInt *CI = dyn_cast(AI->getArraySize()); + assert(CI && "non-constant array size"); + ArraySize = CI->getZExtValue(); + } Type *Ty = AI->getAllocatedType(); uint64_t SizeInBytes = AI->getModule()->getDataLayout().getTypeAllocSize(Ty); - return SizeInBytes; + return SizeInBytes * ArraySize; } /// Check if we want (and can) handle this alloca. bool isInterestingAlloca(AllocaInst &AI); - // Check if we have dynamic alloca. - bool isDynamicAlloca(AllocaInst &AI) const { - return AI.isArrayAllocation() || !AI.isStaticAlloca(); - } - /// If it is an interesting memory access, return the PointerOperand /// and set IsWrite/Alignment. Otherwise return nullptr. Value *isInterestingMemoryAccess(Instruction *I, bool *IsWrite, @@ -721,7 +722,7 @@ struct FunctionStackPoisoner : public InstVisitor { } StackAlignment = std::max(StackAlignment, AI.getAlignment()); - if (ASan.isDynamicAlloca(AI)) + if (!AI.isStaticAlloca()) DynamicAllocaVec.push_back(&AI); else AllocaVec.push_back(&AI); @@ -912,7 +913,7 @@ bool AddressSanitizer::isInterestingAlloca(AllocaInst &AI) { bool IsInteresting = (AI.getAllocatedType()->isSized() && // alloca() may be called with 0 size, ignore it. - getAllocaSizeInBytes(&AI) > 0 && + ((!AI.isStaticAlloca()) || getAllocaSizeInBytes(&AI) > 0) && // We are only interested in allocas not promotable to registers. // Promotable allocas are common under -O0. (!ClSkipPromotableAllocas || !isAllocaPromotable(&AI)) && @@ -2013,7 +2014,7 @@ void FunctionStackPoisoner::poisonStack() { assert(APC.InsBefore); assert(APC.AI); assert(ASan.isInterestingAlloca(*APC.AI)); - bool IsDynamicAlloca = ASan.isDynamicAlloca(*APC.AI); + bool IsDynamicAlloca = !(*APC.AI).isStaticAlloca(); if (!ClInstrumentAllocas && IsDynamicAlloca) continue;