Skip to content

Commit

Permalink
[HWASan] remove incorrectly inferred attributes (llvm#106565)
Browse files Browse the repository at this point in the history
assume all functions used in a HWASan module potentially touch shadow
memory (and short granules).
  • Loading branch information
fmayer authored Aug 29, 2024
1 parent aeedab7 commit f08f9cd
Show file tree
Hide file tree
Showing 9 changed files with 437 additions and 407 deletions.
26 changes: 18 additions & 8 deletions llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -598,6 +598,24 @@ void HWAddressSanitizer::initializeModule() {
LLVM_DEBUG(dbgs() << "Init " << M.getName() << "\n");
TargetTriple = Triple(M.getTargetTriple());

for (auto &F : M.functions()) {
// Remove memory attributes that are invalid with HWASan.
// HWASan checks read from shadow, which invalidates memory(argmem: *)
// Short granule checks on function arguments read from the argument memory
// (last byte of the granule), which invalidates writeonly.
//
// This is not only true for sanitized functions, because AttrInfer can
// infer those attributes on libc functions, which is not true if those
// are instrumented (Android) or intercepted.

// nobuiltin makes sure later passes don't restore assumptions about
// the function.
F.addFnAttr(llvm::Attribute::NoBuiltin);
F.removeFnAttr(llvm::Attribute::Memory);
for (auto &A : F.args())
A.removeAttr(llvm::Attribute::WriteOnly);
}

// x86_64 currently has two modes:
// - Intel LAM (default)
// - pointer aliasing (heap only)
Expand Down Expand Up @@ -1622,14 +1640,6 @@ void HWAddressSanitizer::sanitizeFunction(Function &F,

assert(!ShadowBase);

// Remove memory attributes that are about to become invalid.
// HWASan checks read from shadow, which invalidates memory(argmem: *)
// Short granule checks on function arguments read from the argument memory
// (last byte of the granule), which invalidates writeonly.
F.removeFnAttr(llvm::Attribute::Memory);
for (auto &A : F.args())
A.removeAttr(llvm::Attribute::WriteOnly);

BasicBlock::iterator InsertPt = F.getEntryBlock().begin();
IRBuilder<> EntryIRB(&F.getEntryBlock(), InsertPt);
emitPrologue(EntryIRB,
Expand Down
156 changes: 80 additions & 76 deletions llvm/test/Instrumentation/HWAddressSanitizer/RISCV/alloca.ll

Large diffs are not rendered by default.

270 changes: 134 additions & 136 deletions llvm/test/Instrumentation/HWAddressSanitizer/RISCV/basic.ll

Large diffs are not rendered by default.

160 changes: 82 additions & 78 deletions llvm/test/Instrumentation/HWAddressSanitizer/alloca.ll

Large diffs are not rendered by default.

14 changes: 14 additions & 0 deletions llvm/test/Instrumentation/HWAddressSanitizer/attrinfer.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
; Standard library functions get inferred attributes, some of which are not
; correct when building for HWASan.

; RUN: opt < %s -passes=hwasan -S | FileCheck %s --check-prefixes=CHECK

target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
target triple = "aarch64--linux-android10000"

declare float @frexpf(float noundef, ptr nocapture noundef) local_unnamed_addr #0

attributes #0 = { mustprogress nofree nounwind willreturn memory(argmem: write) "frame-pointer"="non-leaf" "hwasan-abi"="interceptor" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="generic" "target-features"="+fix-cortex-a53-835769,+fp-armv8,+neon,+outline-atomics,+tagged-globals,+v8a" }

; CHECK-NOT: memory(argmem: write)
; CHECK: nobuiltin
208 changes: 104 additions & 104 deletions llvm/test/Instrumentation/HWAddressSanitizer/basic.ll

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions llvm/test/Instrumentation/HWAddressSanitizer/fixed-shadow.ll
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,7 @@ entry:

define i8 @test_load_noattr(ptr %a) {
; CHECK-LABEL: define i8 @test_load_noattr
; CHECK-SAME: (ptr [[A:%.*]]) {
; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR1:[0-9]+]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[B:%.*]] = load i8, ptr [[A]], align 4
; CHECK-NEXT: ret i8 [[B]]
Expand All @@ -206,7 +206,7 @@ entry:

define i8 @test_load_notmyattr(ptr %a) sanitize_address {
; CHECK-LABEL: define i8 @test_load_notmyattr
; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR1:[0-9]+]] {
; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR2:[0-9]+]] {
; CHECK-NEXT: entry:
; CHECK-NEXT: [[B:%.*]] = load i8, ptr [[A]], align 4
; CHECK-NEXT: ret i8 [[B]]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ target triple = "x86_64-unknown-linux-gnu"
; CHECK: @__hwasan_shadow = external global [0 x i8]
;.
define i8 @test_load8(ptr %a) sanitize_hwaddress {
; CHECK: Function Attrs: sanitize_hwaddress
; CHECK: Function Attrs: nobuiltin sanitize_hwaddress
; CHECK-LABEL: define i8 @test_load8
; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {
; CHECK-NEXT: entry:
Expand All @@ -33,7 +33,7 @@ entry:
ret i8 %b
}
;.
; CHECK: attributes #[[ATTR0]] = { sanitize_hwaddress }
; CHECK: attributes #[[ATTR0]] = { nobuiltin sanitize_hwaddress }
; CHECK: attributes #[[ATTR1:[0-9]+]] = { nounwind }
;.
; CHECK: [[META0]] = !{ptr @hwasan.note}
Expand Down
2 changes: 1 addition & 1 deletion llvm/test/Instrumentation/HWAddressSanitizer/mem-attr.ll
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ entry:
ret void
}

; CHECK: attributes #0 = { sanitize_hwaddress uwtable }
; CHECK: attributes #0 = { nobuiltin sanitize_hwaddress uwtable }
attributes #0 = { sanitize_hwaddress memory(argmem: write) uwtable }

0 comments on commit f08f9cd

Please sign in to comment.