Skip to content

Commit f08f9cd

Browse files
authored
[HWASan] remove incorrectly inferred attributes (#106565)
assume all functions used in a HWASan module potentially touch shadow memory (and short granules).
1 parent aeedab7 commit f08f9cd

File tree

9 files changed

+437
-407
lines changed

9 files changed

+437
-407
lines changed

llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,24 @@ void HWAddressSanitizer::initializeModule() {
598598
LLVM_DEBUG(dbgs() << "Init " << M.getName() << "\n");
599599
TargetTriple = Triple(M.getTargetTriple());
600600

601+
for (auto &F : M.functions()) {
602+
// Remove memory attributes that are invalid with HWASan.
603+
// HWASan checks read from shadow, which invalidates memory(argmem: *)
604+
// Short granule checks on function arguments read from the argument memory
605+
// (last byte of the granule), which invalidates writeonly.
606+
//
607+
// This is not only true for sanitized functions, because AttrInfer can
608+
// infer those attributes on libc functions, which is not true if those
609+
// are instrumented (Android) or intercepted.
610+
611+
// nobuiltin makes sure later passes don't restore assumptions about
612+
// the function.
613+
F.addFnAttr(llvm::Attribute::NoBuiltin);
614+
F.removeFnAttr(llvm::Attribute::Memory);
615+
for (auto &A : F.args())
616+
A.removeAttr(llvm::Attribute::WriteOnly);
617+
}
618+
601619
// x86_64 currently has two modes:
602620
// - Intel LAM (default)
603621
// - pointer aliasing (heap only)
@@ -1622,14 +1640,6 @@ void HWAddressSanitizer::sanitizeFunction(Function &F,
16221640

16231641
assert(!ShadowBase);
16241642

1625-
// Remove memory attributes that are about to become invalid.
1626-
// HWASan checks read from shadow, which invalidates memory(argmem: *)
1627-
// Short granule checks on function arguments read from the argument memory
1628-
// (last byte of the granule), which invalidates writeonly.
1629-
F.removeFnAttr(llvm::Attribute::Memory);
1630-
for (auto &A : F.args())
1631-
A.removeAttr(llvm::Attribute::WriteOnly);
1632-
16331643
BasicBlock::iterator InsertPt = F.getEntryBlock().begin();
16341644
IRBuilder<> EntryIRB(&F.getEntryBlock(), InsertPt);
16351645
emitPrologue(EntryIRB,

llvm/test/Instrumentation/HWAddressSanitizer/RISCV/alloca.ll

Lines changed: 80 additions & 76 deletions
Large diffs are not rendered by default.

llvm/test/Instrumentation/HWAddressSanitizer/RISCV/basic.ll

Lines changed: 134 additions & 136 deletions
Large diffs are not rendered by default.

llvm/test/Instrumentation/HWAddressSanitizer/alloca.ll

Lines changed: 82 additions & 78 deletions
Large diffs are not rendered by default.
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
; Standard library functions get inferred attributes, some of which are not
2+
; correct when building for HWASan.
3+
4+
; RUN: opt < %s -passes=hwasan -S | FileCheck %s --check-prefixes=CHECK
5+
6+
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
7+
target triple = "aarch64--linux-android10000"
8+
9+
declare float @frexpf(float noundef, ptr nocapture noundef) local_unnamed_addr #0
10+
11+
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" }
12+
13+
; CHECK-NOT: memory(argmem: write)
14+
; CHECK: nobuiltin

llvm/test/Instrumentation/HWAddressSanitizer/basic.ll

Lines changed: 104 additions & 104 deletions
Large diffs are not rendered by default.

llvm/test/Instrumentation/HWAddressSanitizer/fixed-shadow.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,7 +194,7 @@ entry:
194194

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

207207
define i8 @test_load_notmyattr(ptr %a) sanitize_address {
208208
; CHECK-LABEL: define i8 @test_load_notmyattr
209-
; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR1:[0-9]+]] {
209+
; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR2:[0-9]+]] {
210210
; CHECK-NEXT: entry:
211211
; CHECK-NEXT: [[B:%.*]] = load i8, ptr [[A]], align 4
212212
; CHECK-NEXT: ret i8 [[B]]

llvm/test/Instrumentation/HWAddressSanitizer/hwasan-pass-second-run.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ target triple = "x86_64-unknown-linux-gnu"
1818
; CHECK: @__hwasan_shadow = external global [0 x i8]
1919
;.
2020
define i8 @test_load8(ptr %a) sanitize_hwaddress {
21-
; CHECK: Function Attrs: sanitize_hwaddress
21+
; CHECK: Function Attrs: nobuiltin sanitize_hwaddress
2222
; CHECK-LABEL: define i8 @test_load8
2323
; CHECK-SAME: (ptr [[A:%.*]]) #[[ATTR0:[0-9]+]] {
2424
; CHECK-NEXT: entry:
@@ -33,7 +33,7 @@ entry:
3333
ret i8 %b
3434
}
3535
;.
36-
; CHECK: attributes #[[ATTR0]] = { sanitize_hwaddress }
36+
; CHECK: attributes #[[ATTR0]] = { nobuiltin sanitize_hwaddress }
3737
; CHECK: attributes #[[ATTR1:[0-9]+]] = { nounwind }
3838
;.
3939
; CHECK: [[META0]] = !{ptr @hwasan.note}

llvm/test/Instrumentation/HWAddressSanitizer/mem-attr.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,5 +11,5 @@ entry:
1111
ret void
1212
}
1313

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

0 commit comments

Comments
 (0)