hwasan: Pad arrays with non-1 size correctly.

Spotted by eugenis.

Differential Revision: https://reviews.llvm.org/D64783

llvm-svn: 366171
This commit is contained in:
Peter Collingbourne 2019-07-16 03:25:50 +00:00
parent b2782227ab
commit 07693df04a
5 changed files with 33 additions and 14 deletions

View File

@ -1108,8 +1108,14 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) {
uint64_t AlignedSize = alignTo(Size, Mapping.getAllocaAlignment());
AI->setAlignment(std::max(AI->getAlignment(), 16u));
if (Size != AlignedSize) {
Type *AllocatedType = AI->getAllocatedType();
if (AI->isArrayAllocation()) {
uint64_t ArraySize =
cast<ConstantInt>(AI->getArraySize())->getZExtValue();
AllocatedType = ArrayType::get(AllocatedType, ArraySize);
}
Type *TypeWithPadding = StructType::get(
AI->getAllocatedType(), ArrayType::get(Int8Ty, AlignedSize - Size));
AllocatedType, ArrayType::get(Int8Ty, AlignedSize - Size));
auto *NewAI = new AllocaInst(
TypeWithPadding, AI->getType()->getAddressSpace(), nullptr, "", AI);
NewAI->takeName(AI);
@ -1117,10 +1123,8 @@ bool HWAddressSanitizer::sanitizeFunction(Function &F) {
NewAI->setUsedWithInAlloca(AI->isUsedWithInAlloca());
NewAI->setSwiftError(AI->isSwiftError());
NewAI->copyMetadata(*AI);
Value *Zero = ConstantInt::get(Int32Ty, 0);
auto *GEP = GetElementPtrInst::Create(TypeWithPadding, NewAI,
{Zero, Zero}, "", AI);
AI->replaceAllUsesWith(GEP);
auto *Bitcast = new BitCastInst(NewAI, AI->getType(), "", AI);
AI->replaceAllUsesWith(Bitcast);
AllocaToPaddedAllocaMap[AI] = NewAI;
}
}

View File

@ -0,0 +1,15 @@
; RUN: opt < %s -hwasan -S | FileCheck %s
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
target triple = "aarch64--linux-android"
declare void @use(i8*, i8*)
define void @test_alloca() sanitize_hwaddress {
; CHECK: alloca { [4 x i8], [12 x i8] }, align 16
%x = alloca i8, i64 4
; CHECK: alloca i8, i64 16, align 16
%y = alloca i8, i64 16
call void @use(i8* %x, i8* %y)
ret void
}

View File

@ -9,10 +9,10 @@ declare void @use32(i32*)
define void @test_alloca() sanitize_hwaddress {
; CHECK-LABEL: @test_alloca(
; CHECK: %[[GEP:[^ ]*]] = getelementptr { i32, [12 x i8] }, { i32, [12 x i8] }* %x, i32 0, i32 0
; CHECK: %[[BC:[^ ]*]] = bitcast { i32, [12 x i8] }* %x to i32*
; CHECK: %[[T1:[^ ]*]] = call i8 @__hwasan_generate_tag()
; CHECK: %[[A:[^ ]*]] = zext i8 %[[T1]] to i64
; CHECK: %[[B:[^ ]*]] = ptrtoint i32* %[[GEP]] to i64
; CHECK: %[[B:[^ ]*]] = ptrtoint i32* %[[BC]] to i64
; CHECK: %[[C:[^ ]*]] = shl i64 %[[A]], 56
; CHECK: or i64 %[[B]], %[[C]]

View File

@ -17,28 +17,28 @@ define void @test_alloca() sanitize_hwaddress {
; CHECK: %[[BASE_TAG:[^ ]*]] = xor i64 %[[A]], %[[B]]
; CHECK: %[[X:[^ ]*]] = alloca { i32, [12 x i8] }, align 16
; CHECK: %[[X_GEP:[^ ]*]] = getelementptr { i32, [12 x i8] }, { i32, [12 x i8] }* %[[X]], i32 0, i32 0
; CHECK: %[[X_BC:[^ ]*]] = bitcast { i32, [12 x i8] }* %[[X]] to i32*
; CHECK: %[[X_TAG:[^ ]*]] = xor i64 %[[BASE_TAG]], 0
; CHECK: %[[X1:[^ ]*]] = ptrtoint i32* %[[X_GEP]] to i64
; CHECK: %[[X1:[^ ]*]] = ptrtoint i32* %[[X_BC]] to i64
; CHECK: %[[C:[^ ]*]] = shl i64 %[[X_TAG]], 56
; CHECK: %[[D:[^ ]*]] = or i64 %[[X1]], %[[C]]
; CHECK: %[[X_HWASAN:[^ ]*]] = inttoptr i64 %[[D]] to i32*
; CHECK: %[[X_TAG2:[^ ]*]] = trunc i64 %[[X_TAG]] to i8
; CHECK: %[[E:[^ ]*]] = ptrtoint i32* %[[X_GEP]] to i64
; CHECK: %[[E:[^ ]*]] = ptrtoint i32* %[[X_BC]] to i64
; CHECK: %[[F:[^ ]*]] = lshr i64 %[[E]], 4
; DYNAMIC-SHADOW: %[[X_SHADOW:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %[[F]]
; ZERO-BASED-SHADOW: %[[X_SHADOW:[^ ]*]] = inttoptr i64 %[[F]] to i8*
; CHECK: %[[X_SHADOW_GEP:[^ ]*]] = getelementptr i8, i8* %[[X_SHADOW]], i32 0
; CHECK: store i8 4, i8* %[[X_SHADOW_GEP]]
; CHECK: %[[X_I8:[^ ]*]] = bitcast i32* %[[X_GEP]] to i8*
; CHECK: %[[X_I8:[^ ]*]] = bitcast i32* %[[X_BC]] to i8*
; CHECK: %[[X_I8_GEP:[^ ]*]] = getelementptr i8, i8* %[[X_I8]], i32 15
; CHECK: store i8 %[[X_TAG2]], i8* %[[X_I8_GEP]]
; CHECK: call void @use32(i32* nonnull %[[X_HWASAN]])
; UAR-TAGS: %[[BASE_TAG_COMPL:[^ ]*]] = xor i64 %[[BASE_TAG]], 255
; UAR-TAGS: %[[X_TAG_UAR:[^ ]*]] = trunc i64 %[[BASE_TAG_COMPL]] to i8
; CHECK: %[[E2:[^ ]*]] = ptrtoint i32* %[[X_GEP]] to i64
; CHECK: %[[E2:[^ ]*]] = ptrtoint i32* %[[X_BC]] to i64
; CHECK: %[[F2:[^ ]*]] = lshr i64 %[[E2]], 4
; DYNAMIC-SHADOW: %[[X_SHADOW2:[^ ]*]] = getelementptr i8, i8* %.hwasan.shadow, i64 %[[F2]]
; ZERO-BASED-SHADOW: %[[X_SHADOW2:[^ ]*]] = inttoptr i64 %[[F2]] to i8*

View File

@ -15,9 +15,9 @@ define void @test_alloca() sanitize_hwaddress {
; CHECK: %[[BASE_TAG:[^ ]*]] = xor i64 %[[A]], %[[B]]
; CHECK: %[[X:[^ ]*]] = alloca { i32, [12 x i8] }, align 16
; CHECK: %[[X_GEP:[^ ]*]] = getelementptr { i32, [12 x i8] }, { i32, [12 x i8] }* %[[X]], i32 0, i32 0
; CHECK: %[[X_BC:[^ ]*]] = bitcast { i32, [12 x i8] }* %[[X]] to i32*
; CHECK: %[[X_TAG:[^ ]*]] = xor i64 %[[BASE_TAG]], 0
; CHECK: %[[X1:[^ ]*]] = ptrtoint i32* %[[X_GEP]] to i64
; CHECK: %[[X1:[^ ]*]] = ptrtoint i32* %[[X_BC]] to i64
; CHECK: %[[C:[^ ]*]] = shl i64 %[[X_TAG]], 56
; CHECK: %[[D:[^ ]*]] = or i64 %[[C]], 72057594037927935
; CHECK: %[[E:[^ ]*]] = and i64 %[[X1]], %[[D]]