llvm.org GIT mirror llvm / 95e3cf4
[asan] unpoison the stack before every noreturn call. Fixes asan issue 37. llvm part git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@150102 91177308-0d34-0410-b5e6-96231b3b80d8 Kostya Serebryany 7 years ago
2 changed file(s) with 34 addition(s) and 2 deletion(s). Raw diff Collapse all Expand all
5959 static const char *kAsanRegisterGlobalsName = "__asan_register_globals";
6060 static const char *kAsanUnregisterGlobalsName = "__asan_unregister_globals";
6161 static const char *kAsanInitName = "__asan_init";
62 static const char *kAsanHandleNoReturnName = "__asan_handle_no_return";
6263 static const char *kAsanMappingOffsetName = "__asan_mapping_offset";
6364 static const char *kAsanMappingScaleName = "__asan_mapping_scale";
6465 static const char *kAsanStackMallocName = "__asan_stack_malloc";
648649 // (unless there are calls between uses).
649650 SmallSet TempsToInstrument;
650651 SmallVector ToInstrument;
652 SmallVector NoReturnCalls;
651653
652654 // Fill the set of memory operations to instrument.
653655 for (Function::iterator FI = F.begin(), FE = F.end();
666668 } else if (isa(BI) && ClMemIntrin) {
667669 // ok, take it.
668670 } else {
669 if (isa(BI)) {
671 if (CallInst *CI = dyn_cast(BI)) {
670672 // A call inside BB.
671673 TempsToInstrument.clear();
674 if (CI->doesNotReturn()) {
675 NoReturnCalls.push_back(CI);
676 }
672677 }
673678 continue;
674679 }
693698 DEBUG(dbgs() << F);
694699
695700 bool ChangedStack = poisonStackInFunction(M, F);
696 return NumInstrumented > 0 || ChangedStack;
701
702 // We must unpoison the stack before every NoReturn call (throw, _exit, etc).
703 // See e.g. http://code.google.com/p/address-sanitizer/issues/detail?id=37
704 for (size_t i = 0, n = NoReturnCalls.size(); i != n; i++) {
705 Instruction *CI = NoReturnCalls[i];
706 IRBuilder<> IRB(CI);
707 IRB.CreateCall(M.getOrInsertFunction(kAsanHandleNoReturnName,
708 IRB.getVoidTy(), NULL));
709 }
710
711 return NumInstrumented > 0 || ChangedStack || !NoReturnCalls.empty();
697712 }
698713
699714 static uint64_t ValueForPoison(uint64_t PoisonByte, size_t ShadowRedzoneSize) {
0 ; RUN: opt < %s -asan -S | FileCheck %s
1 ; AddressSanitizer must insert __asan_handle_no_return
2 ; before every noreturn call.
3
4 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"
5 target triple = "x86_64-unknown-linux-gnu"
6
7 declare void @MyNoReturnFunc(i32) noreturn
8
9 define i32 @_Z5ChildPv(i8* nocapture %arg) uwtable address_safety {
10 entry:
11 call void @MyNoReturnFunc(i32 1) noreturn
12 unreachable
13 }
14
15 ; CHECK: call void @__asan_handle_no_return
16 ; CHECK-NEXT: call void @MyNoReturnFunc