From 64409ad8e3b360b84349042f14b57f87a5c0ca18 Mon Sep 17 00:00:00 2001 From: Alexey Samsonov Date: Mon, 18 Nov 2013 14:53:55 +0000 Subject: [PATCH] [ASan] Fix PR17867 - make sure ASan doesn't crash if use-after-scope and use-after-return are combined. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@195014 91177308-0d34-0410-b5e6-96231b3b80d8 --- .../Instrumentation/AddressSanitizer.cpp | 12 +++---- .../AddressSanitizer/lifetime-uar.ll | 33 +++++++++++++++++++ .../AddressSanitizer/lifetime.ll | 6 ++-- 3 files changed, 42 insertions(+), 9 deletions(-) create mode 100644 test/Instrumentation/AddressSanitizer/lifetime-uar.ll diff --git a/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/lib/Transforms/Instrumentation/AddressSanitizer.cpp index d8c3f8eafb7..d731ec5499e 100644 --- a/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -426,6 +426,7 @@ struct FunctionStackPoisoner : public InstVisitor { // Stores a place and arguments of poisoning/unpoisoning call for alloca. struct AllocaPoisonCall { IntrinsicInst *InsBefore; + AllocaInst *AI; uint64_t Size; bool DoPoison; }; @@ -504,7 +505,7 @@ struct FunctionStackPoisoner : public InstVisitor { AllocaInst *AI = findAllocaForValue(II.getArgOperand(1)); if (!AI) return; bool DoPoison = (ID == Intrinsic::lifetime_end); - AllocaPoisonCall APC = {&II, SizeValue, DoPoison}; + AllocaPoisonCall APC = {&II, AI, SizeValue, DoPoison}; AllocaPoisonCallVec.push_back(APC); } @@ -1523,11 +1524,10 @@ void FunctionStackPoisoner::poisonStack() { bool HavePoisonedAllocas = false; for (size_t i = 0, n = AllocaPoisonCallVec.size(); i < n; i++) { const AllocaPoisonCall &APC = AllocaPoisonCallVec[i]; - IntrinsicInst *II = APC.InsBefore; - AllocaInst *AI = findAllocaForValue(II->getArgOperand(1)); - assert(AI); - IRBuilder<> IRB(II); - poisonAlloca(AI, APC.Size, IRB, APC.DoPoison); + assert(APC.InsBefore); + assert(APC.AI); + IRBuilder<> IRB(APC.InsBefore); + poisonAlloca(APC.AI, APC.Size, IRB, APC.DoPoison); HavePoisonedAllocas |= APC.DoPoison; } diff --git a/test/Instrumentation/AddressSanitizer/lifetime-uar.ll b/test/Instrumentation/AddressSanitizer/lifetime-uar.ll new file mode 100644 index 00000000000..21eaf7f1541 --- /dev/null +++ b/test/Instrumentation/AddressSanitizer/lifetime-uar.ll @@ -0,0 +1,33 @@ +; Test handling of llvm.lifetime intrinsics in UAR mode. +; RUN: opt < %s -asan -asan-use-after-return -asan-check-lifetime -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-S128" + +declare void @llvm.lifetime.start(i64, i8* nocapture) nounwind +declare void @llvm.lifetime.end(i64, i8* nocapture) nounwind + +define i32 @basic_test() sanitize_address { + ; CHECK-LABEL: define i32 @basic_test() + +entry: + %retval = alloca i32, align 4 + %c = alloca i8, align 1 + + call void @llvm.lifetime.start(i64 1, i8* %c) + ; Memory is unpoisoned at llvm.lifetime.start + ; CHECK: call void @__asan_unpoison_stack_memory(i64 %{{[^ ]+}}, i64 1) + + store i32 0, i32* %retval + store i8 0, i8* %c, align 1 + + call void @llvm.lifetime.end(i64 1, i8* %c) + ; Memory is poisoned at llvm.lifetime.end + ; CHECK: call void @__asan_poison_stack_memory(i64 %{{[^ ]+}}, i64 1) + + ; No need to unpoison memory at function exit in UAR mode. + ; CHECK-NOT: @__asan_unpoison_stack_memory + ; CHECK: ret void + + ret i32 0 +} + diff --git a/test/Instrumentation/AddressSanitizer/lifetime.ll b/test/Instrumentation/AddressSanitizer/lifetime.ll index 334872865f1..d80331e3872 100644 --- a/test/Instrumentation/AddressSanitizer/lifetime.ll +++ b/test/Instrumentation/AddressSanitizer/lifetime.ll @@ -15,7 +15,7 @@ entry: call void @llvm.lifetime.end(i64 -1, i8* %i.ptr) ; Check that lifetime with no size are ignored. -; CHECK: @lifetime_no_size +; CHECK-LABEL: define void @lifetime_no_size() ; CHECK-NOT: @__asan_poison_stack_memory ; CHECK-NOT: @__asan_unpoison_stack_memory ; CHECK: ret void @@ -24,7 +24,7 @@ entry: ; Generic case of lifetime analysis. define void @lifetime() sanitize_address { - ; CHECK: @lifetime + ; CHECK-LABEL: define void @lifetime() ; Regular variable lifetime intrinsics. %i = alloca i32, align 4 @@ -62,7 +62,7 @@ define void @lifetime() sanitize_address { ; Check that arguments of lifetime may come from phi nodes. define void @phi_args(i1 %x) sanitize_address { - ; CHECK: @phi_args + ; CHECK-LABEL: define void @phi_args(i1 %x) entry: %i = alloca i64, align 4 -- 2.34.1