[hwasan] LLVM-level flags for linux kernel-compatible hwasan instrumentation.

Summary:
-hwasan-mapping-offset defines the non-zero shadow base address.
-hwasan-kernel disables calls to __hwasan_init in module constructors.
Unlike ASan, -hwasan-kernel does not force callback instrumentation.
This is controlled separately with -hwasan-instrument-with-calls.

Reviewers: kcc

Subscribers: srhines, hiraditya, llvm-commits

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

llvm-svn: 322785
This commit is contained in:
Evgeniy Stepanov 2018-01-17 23:24:38 +00:00
parent fd2833992a
commit 5bd669dc8f
2 changed files with 50 additions and 7 deletions

View File

@ -96,6 +96,15 @@ static cl::opt<bool> ClGenerateTagsWithCalls(
cl::desc("generate new tags with runtime library calls"), cl::Hidden,
cl::init(false));
static cl::opt<unsigned long long> ClMappingOffset(
"hwasan-mapping-offset",
cl::desc("offset of hwasan shadow mapping [EXPERIMENTAL]"), cl::Hidden,
cl::init(0));
static cl::opt<bool> ClEnableKhwasan(
"hwasan-kernel", cl::desc("Enable KernelHWAddressSanitizer instrumentation"),
cl::Hidden, cl::init(false));
namespace {
/// \brief An instrumentation pass implementing detection of addressability bugs
@ -177,12 +186,14 @@ bool HWAddressSanitizer::doInitialization(Module &M) {
IntptrTy = IRB.getIntPtrTy(DL);
Int8Ty = IRB.getInt8Ty();
std::tie(HwasanCtorFunction, std::ignore) =
createSanitizerCtorAndInitFunctions(M, kHwasanModuleCtorName,
kHwasanInitName,
/*InitArgTypes=*/{},
/*InitArgs=*/{});
appendToGlobalCtors(M, HwasanCtorFunction, 0);
if (!ClEnableKhwasan) {
std::tie(HwasanCtorFunction, std::ignore) =
createSanitizerCtorAndInitFunctions(M, kHwasanModuleCtorName,
kHwasanInitName,
/*InitArgTypes=*/{},
/*InitArgs=*/{});
appendToGlobalCtors(M, HwasanCtorFunction, 0);
}
return true;
}
@ -282,7 +293,12 @@ void HWAddressSanitizer::instrumentMemAccessInline(Value *PtrLong, bool IsWrite,
IRB.CreateAnd(PtrLong, ConstantInt::get(PtrLong->getType(),
~(0xFFULL << kPointerTagShift)));
Value *ShadowLong = IRB.CreateLShr(AddrLong, kShadowScale);
Value *MemTag = IRB.CreateLoad(IRB.CreateIntToPtr(ShadowLong, IRB.getInt8PtrTy()));
if (ClMappingOffset)
ShadowLong = IRB.CreateAdd(
ShadowLong, ConstantInt::get(PtrLong->getType(), ClMappingOffset,
/*isSigned=*/false));
Value *MemTag =
IRB.CreateLoad(IRB.CreateIntToPtr(ShadowLong, IRB.getInt8PtrTy()));
Value *TagMismatch = IRB.CreateICmpNE(PtrTag, MemTag);
TerminatorInst *CheckTerm =

View File

@ -0,0 +1,27 @@
; Test kernel hwasan instrumentation.
;
; RUN: opt < %s -hwasan -hwasan-kernel=1 -S | FileCheck %s --allow-empty --check-prefixes=KERNEL
; RUN: opt < %s -hwasan -hwasan-mapping-offset=12345678 -S | FileCheck %s --check-prefixes=OFFSET
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
target triple = "aarch64--linux-android"
define i8 @test_load(i8* %a) sanitize_hwaddress {
; OFFSET-LABEL: @test_load(
; OFFSET: %[[A:[^ ]*]] = ptrtoint i8* %a to i64
; OFFSET: %[[B:[^ ]*]] = lshr i64 %[[A]], 56
; OFFSET: %[[PTRTAG:[^ ]*]] = trunc i64 %[[B]] to i8
; OFFSET: %[[C:[^ ]*]] = and i64 %[[A]], 72057594037927935
; OFFSET: %[[D:[^ ]*]] = lshr i64 %[[C]], 4
; OFFSET: %[[D1:[^ ]*]] = add i64 %[[D]], 12345678
; OFFSET: %[[E:[^ ]*]] = inttoptr i64 %[[D1]] to i8*
; OFFSET: %[[MEMTAG:[^ ]*]] = load i8, i8* %[[E]]
; OFFSET: %[[F:[^ ]*]] = icmp ne i8 %[[PTRTAG]], %[[MEMTAG]]
; OFFSET: br i1 %[[F]],
entry:
%b = load i8, i8* %a, align 4
ret i8 %b
}
; KERNEL-NOT: call void @__hwasan_init