mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-07-24 22:24:54 +00:00
[asan] don't unpoison redzones on function exit in use-after-return mode.
Summary: Before this change the instrumented code before Ret instructions looked like: <Unpoison Frame Redzones> if (Frame != OriginalFrame) // I.e. Frame is fake <Poison Complete Frame> Now the instrumented code looks like: if (Frame != OriginalFrame) // I.e. Frame is fake <Poison Complete Frame> else <Unpoison Frame Redzones> Reviewers: eugenis Reviewed By: eugenis CC: llvm-commits Differential Revision: http://llvm-reviews.chandlerc.com/D2458 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@197907 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@@ -1508,27 +1508,31 @@ void FunctionStackPoisoner::poisonStack() {
|
||||
Value *ShadowBase = ASan.memToShadow(LocalStackBase, IRB);
|
||||
poisonRedZones(L.ShadowBytes, IRB, ShadowBase, true);
|
||||
|
||||
// Unpoison the stack before all ret instructions.
|
||||
// (Un)poison the stack before all ret instructions.
|
||||
for (size_t i = 0, n = RetVec.size(); i < n; i++) {
|
||||
Instruction *Ret = RetVec[i];
|
||||
IRBuilder<> IRBRet(Ret);
|
||||
// Mark the current frame as retired.
|
||||
IRBRet.CreateStore(ConstantInt::get(IntptrTy, kRetiredStackFrameMagic),
|
||||
BasePlus0);
|
||||
// Unpoison the stack.
|
||||
poisonRedZones(L.ShadowBytes, IRBRet, ShadowBase, false);
|
||||
if (DoStackMalloc) {
|
||||
assert(StackMallocIdx >= 0);
|
||||
// In use-after-return mode, mark the whole stack frame unaddressable.
|
||||
// if LocalStackBase != OrigStackBase:
|
||||
// // In use-after-return mode, poison the whole stack frame.
|
||||
// if StackMallocIdx <= 4
|
||||
// // For small sizes inline the whole thing:
|
||||
// memset(ShadowBase, kAsanStackAfterReturnMagic, ShadowSize);
|
||||
// **SavedFlagPtr(LocalStackBase) = 0
|
||||
// else
|
||||
// __asan_stack_free_N(LocalStackBase, OrigStackBase)
|
||||
// else
|
||||
// <This is not a fake stack; unpoison the redzones>
|
||||
Value *Cmp = IRBRet.CreateICmpNE(LocalStackBase, OrigStackBase);
|
||||
TerminatorInst *ThenTerm, *ElseTerm;
|
||||
SplitBlockAndInsertIfThenElse(Cmp, Ret, &ThenTerm, &ElseTerm);
|
||||
|
||||
IRBuilder<> IRBPoison(ThenTerm);
|
||||
if (StackMallocIdx <= 4) {
|
||||
// For small sizes inline the whole thing:
|
||||
// if LocalStackBase != OrigStackBase:
|
||||
// memset(ShadowBase, kAsanStackAfterReturnMagic, ShadowSize);
|
||||
// **SavedFlagPtr(LocalStackBase) = 0
|
||||
// FIXME: if LocalStackBase != OrigStackBase don't call poisonRedZones.
|
||||
Value *Cmp = IRBRet.CreateICmpNE(LocalStackBase, OrigStackBase);
|
||||
TerminatorInst *PoisonTerm = SplitBlockAndInsertIfThen(Cmp, Ret, false);
|
||||
IRBuilder<> IRBPoison(PoisonTerm);
|
||||
int ClassSize = kMinStackMallocSize << StackMallocIdx;
|
||||
SetShadowToStackAfterReturnInlined(IRBPoison, ShadowBase,
|
||||
ClassSize >> Mapping.Scale);
|
||||
@@ -1542,15 +1546,20 @@ void FunctionStackPoisoner::poisonStack() {
|
||||
IRBPoison.CreateIntToPtr(SavedFlagPtr, IRBPoison.getInt8PtrTy()));
|
||||
} else {
|
||||
// For larger frames call __asan_stack_free_*.
|
||||
IRBRet.CreateCall3(AsanStackFreeFunc[StackMallocIdx], LocalStackBase,
|
||||
ConstantInt::get(IntptrTy, LocalStackSize),
|
||||
OrigStackBase);
|
||||
IRBPoison.CreateCall3(AsanStackFreeFunc[StackMallocIdx], LocalStackBase,
|
||||
ConstantInt::get(IntptrTy, LocalStackSize),
|
||||
OrigStackBase);
|
||||
}
|
||||
|
||||
IRBuilder<> IRBElse(ElseTerm);
|
||||
poisonRedZones(L.ShadowBytes, IRBElse, ShadowBase, false);
|
||||
} else if (HavePoisonedAllocas) {
|
||||
// If we poisoned some allocas in llvm.lifetime analysis,
|
||||
// unpoison whole stack frame now.
|
||||
assert(LocalStackBase == OrigStackBase);
|
||||
poisonAlloca(LocalStackBase, LocalStackSize, IRBRet, false);
|
||||
} else {
|
||||
poisonRedZones(L.ShadowBytes, IRBRet, ShadowBase, false);
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user