[llvm] [HWASan] remove incorrectly inferred attributes (PR #106565)

Florian Mayer via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 29 10:02:36 PDT 2024


https://github.com/fmayer updated https://github.com/llvm/llvm-project/pull/106565

>From 6ec76c973e8c628183ddbffd9fb0be0b17e886ed Mon Sep 17 00:00:00 2001
From: Florian Mayer <fmayer at google.com>
Date: Thu, 29 Aug 2024 08:06:49 -0700
Subject: [PATCH 1/3] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?=
 =?UTF-8?q?itial=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Created using spr 1.3.4
---
 .../Instrumentation/HWAddressSanitizer.cpp    | 22 ++++++++++++-------
 .../HWAddressSanitizer/attrinfer.ll           | 13 +++++++++++
 2 files changed, 27 insertions(+), 8 deletions(-)
 create mode 100644 llvm/test/Instrumentation/HWAddressSanitizer/attrinfer.ll

diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
index 95433a216b168d..15d836a18d64fd 100644
--- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -598,6 +598,20 @@ 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.
+    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)
@@ -1622,14 +1636,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,
diff --git a/llvm/test/Instrumentation/HWAddressSanitizer/attrinfer.ll b/llvm/test/Instrumentation/HWAddressSanitizer/attrinfer.ll
new file mode 100644
index 00000000000000..46a9bbb0a6d894
--- /dev/null
+++ b/llvm/test/Instrumentation/HWAddressSanitizer/attrinfer.ll
@@ -0,0 +1,13 @@
+; 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)
\ No newline at end of file

>From 9b2c7b31a58bb9fc0763cf05cd76d8e6a0c99007 Mon Sep 17 00:00:00 2001
From: Florian Mayer <fmayer at google.com>
Date: Thu, 29 Aug 2024 08:07:55 -0700
Subject: [PATCH 2/3] fmt

Created using spr 1.3.4
---
 llvm/test/Instrumentation/HWAddressSanitizer/attrinfer.ll | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/test/Instrumentation/HWAddressSanitizer/attrinfer.ll b/llvm/test/Instrumentation/HWAddressSanitizer/attrinfer.ll
index 46a9bbb0a6d894..5a39bb9d5e5767 100644
--- a/llvm/test/Instrumentation/HWAddressSanitizer/attrinfer.ll
+++ b/llvm/test/Instrumentation/HWAddressSanitizer/attrinfer.ll
@@ -10,4 +10,4 @@ declare float @frexpf(float noundef, ptr nocapture noundef) local_unnamed_addr #
 
 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)
\ No newline at end of file
+; CHECK-NOT: memory(argmem: write)

>From 97a406276e85583e07a1b18ee06d5ba1085c669b Mon Sep 17 00:00:00 2001
From: Florian Mayer <fmayer at google.com>
Date: Thu, 29 Aug 2024 10:02:22 -0700
Subject: [PATCH 3/3] nobuiltin

Created using spr 1.3.4
---
 llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp | 4 ++++
 llvm/test/Instrumentation/HWAddressSanitizer/attrinfer.ll  | 1 +
 2 files changed, 5 insertions(+)

diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
index 15d836a18d64fd..f5faf117f69bdd 100644
--- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -607,6 +607,10 @@ void HWAddressSanitizer::initializeModule() {
     // 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);
diff --git a/llvm/test/Instrumentation/HWAddressSanitizer/attrinfer.ll b/llvm/test/Instrumentation/HWAddressSanitizer/attrinfer.ll
index 5a39bb9d5e5767..eeb51aeda1000b 100644
--- a/llvm/test/Instrumentation/HWAddressSanitizer/attrinfer.ll
+++ b/llvm/test/Instrumentation/HWAddressSanitizer/attrinfer.ll
@@ -11,3 +11,4 @@ declare float @frexpf(float noundef, ptr nocapture noundef) local_unnamed_addr #
 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



More information about the llvm-commits mailing list