From baf54069ad386b7ede121654577ed4165d42a0b0 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Tue, 13 Oct 2020 10:21:45 -0700 Subject: [PATCH] [ASAN] Make sure we are only processing lifetime markers with offset 0 to alloca This patch addresses https://bugs.llvm.org/show_bug.cgi?id=47787 (and hence https://bugs.llvm.org/show_bug.cgi?id=47767 as well). In latter instrumentation code, we always use the beginning of the alloca as the base for instrumentation, ignoring any offset into the alloca. Because of that, we should only instrument a lifetime marker if it's actually pointing to the beginning of the alloca. Differential Revision: https://reviews.llvm.org/D89191 --- .../Instrumentation/AddressSanitizer.cpp | 4 ++- .../alloca-offset-lifetime.ll | 28 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 test/Instrumentation/AddressSanitizer/alloca-offset-lifetime.ll diff --git a/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/lib/Transforms/Instrumentation/AddressSanitizer.cpp index 2d4e94386e4..8e3b645aad2 100644 --- a/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -1083,7 +1083,9 @@ struct FunctionStackPoisoner : public InstVisitor { !ConstantInt::isValueValidForType(IntptrTy, SizeValue)) return; // Find alloca instruction that corresponds to llvm.lifetime argument. - AllocaInst *AI = findAllocaForValue(II.getArgOperand(1)); + // Currently we can only handle lifetime markers pointing to the + // beginning of the alloca. + AllocaInst *AI = findAllocaForValue(II.getArgOperand(1), true); if (!AI) { HasUntracedLifetimeIntrinsic = true; return; diff --git a/test/Instrumentation/AddressSanitizer/alloca-offset-lifetime.ll b/test/Instrumentation/AddressSanitizer/alloca-offset-lifetime.ll new file mode 100644 index 00000000000..d4bacbcae4d --- /dev/null +++ b/test/Instrumentation/AddressSanitizer/alloca-offset-lifetime.ll @@ -0,0 +1,28 @@ +; Test that ASAN will not instrument lifetime markers on alloca offsets. +; +; RUN: opt < %s --asan --asan-use-after-scope -S | FileCheck %s + +target datalayout = "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-apple-macosx10.15.0" + +%t = type { void (%t*)*, void (%t*)*, %sub, i64 } +%sub = type { i32 } + +define void @foo() sanitize_address { +entry: + %0 = alloca %t, align 8 + %x = getelementptr inbounds %t, %t* %0, i64 0, i32 2 + %1 = bitcast %sub* %x to i8* + call void @llvm.lifetime.start.p0i8(i64 4, i8* nonnull %1) + call void @bar(%sub* nonnull %x) + call void @llvm.lifetime.end.p0i8(i64 4, i8* nonnull %1) #3 + ret void +} + +declare void @llvm.lifetime.start.p0i8(i64 immarg, i8* nocapture) +declare void @bar(%sub*) +declare void @llvm.lifetime.end.p0i8(i64 immarg, i8* nocapture) + +; CHECK: store i64 %[[STACK_BASE:.+]], i64* %asan_local_stack_base, align 8 +; CHECK-NOT: store i8 0 +; CHECK: call void @bar(%sub* nonnull %x)