[llvm] [Instrumentation] Do not run sanitizers for naked functions (PR #108552)

Antonio Frighetto via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 15 06:19:51 PDT 2024


https://github.com/antoniofrighetto updated https://github.com/llvm/llvm-project/pull/108552

>From 331b451d45e3ae2599a9c8ed2650971369e88862 Mon Sep 17 00:00:00 2001
From: Antonio Frighetto <me at antoniofrighetto.com>
Date: Sat, 14 Sep 2024 16:45:42 +0200
Subject: [PATCH 1/2] [Instrumentation] Precommit tests for PR108552 (NFC)

---
 llvm/test/Instrumentation/sanitizers-naked.ll | 113 ++++++++++++++++++
 1 file changed, 113 insertions(+)
 create mode 100644 llvm/test/Instrumentation/sanitizers-naked.ll

diff --git a/llvm/test/Instrumentation/sanitizers-naked.ll b/llvm/test/Instrumentation/sanitizers-naked.ll
new file mode 100644
index 00000000000000..4a28153a036e91
--- /dev/null
+++ b/llvm/test/Instrumentation/sanitizers-naked.ll
@@ -0,0 +1,113 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=asan -S | FileCheck %s --check-prefixes=CHECK-ASAN
+; RUN: opt < %s -passes=tsan -S | FileCheck %s --check-prefixes=CHECK-TSAN
+; RUN: opt < %s -passes=msan -S | FileCheck %s --check-prefixes=CHECK-MSAN
+; RUN: opt < %s -passes=hwasan -S | FileCheck %s --check-prefixes=CHECK-HWASAN
+; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=3 -sanitizer-coverage-control-flow -S | FileCheck %s --check-prefixes=CHECK-SANCOV
+; RUN: opt < %s -passes='module(sanmd-module)' -sanitizer-metadata-atomics -S | FileCheck %s --check-prefixes=CHECK-SANMD
+
+; REQUIRES: x86-registered-target
+
+target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+define void @naked_function(ptr byval(i32) %p) {
+; CHECK-ASAN-LABEL: define void @naked_function(
+; CHECK-ASAN-SAME: ptr byval(i32) [[P:%.*]]) {
+; CHECK-ASAN-NEXT:    call void asm sideeffect "nop", ""()
+; CHECK-ASAN-NEXT:    unreachable
+;
+; CHECK-TSAN-LABEL: define void @naked_function(
+; CHECK-TSAN-SAME: ptr byval(i32) [[P:%.*]]) personality ptr @__gcc_personality_v0 {
+; CHECK-TSAN-NEXT:    [[TMP1:%.*]] = call ptr @llvm.returnaddress(i32 0)
+; CHECK-TSAN-NEXT:    call void @__tsan_func_entry(ptr [[TMP1]])
+; CHECK-TSAN-NEXT:    invoke void asm sideeffect "nop", ""()
+; CHECK-TSAN-NEXT:            to [[DOTNOEXC:label %.*]] unwind label %[[TSAN_CLEANUP:.*]]
+; CHECK-TSAN:       [[_NOEXC:.*:]]
+; CHECK-TSAN-NEXT:    unreachable
+; CHECK-TSAN:       [[TSAN_CLEANUP]]:
+; CHECK-TSAN-NEXT:    [[CLEANUP_LPAD:%.*]] = landingpad { ptr, i32 }
+; CHECK-TSAN-NEXT:            cleanup
+; CHECK-TSAN-NEXT:    call void @__tsan_func_exit()
+; CHECK-TSAN-NEXT:    resume { ptr, i32 } [[CLEANUP_LPAD]]
+;
+; CHECK-MSAN-LABEL: define void @naked_function(
+; CHECK-MSAN-SAME: ptr byval(i32) [[P:%.*]]) {
+; CHECK-MSAN-NEXT:    call void @llvm.donothing()
+; CHECK-MSAN-NEXT:    call void asm sideeffect "nop", ""()
+; CHECK-MSAN-NEXT:    unreachable
+;
+; CHECK-HWASAN-LABEL: define void @naked_function(
+; CHECK-HWASAN-SAME: ptr byval(i32) [[P:%.*]]) {
+; CHECK-HWASAN-NEXT:    call void asm sideeffect "nop", ""()
+; CHECK-HWASAN-NEXT:    unreachable
+;
+; CHECK-SANCOV-LABEL: define void @naked_function(
+; CHECK-SANCOV-SAME: ptr byval(i32) [[P:%.*]]) {
+; CHECK-SANCOV-NEXT:    call void asm sideeffect "nop", ""()
+; CHECK-SANCOV-NEXT:    unreachable
+;
+; CHECK-SANMD-LABEL: define void @naked_function(
+; CHECK-SANMD-SAME: ptr byval(i32) [[P:%.*]]) !pcsections [[META0:![0-9]+]] {
+; CHECK-SANMD-NEXT:    call void asm sideeffect "nop", ""()
+; CHECK-SANMD-NEXT:    unreachable
+;
+  call void asm sideeffect "nop", ""()
+  unreachable
+}
+
+define void @naked_function_with_asan(ptr byval(i32) %p) sanitize_address {
+; CHECK-ASAN-LABEL: define void @naked_function_with_asan(
+; CHECK-ASAN-SAME: ptr byval(i32) [[P:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-ASAN-NEXT:    [[P_BYVAL:%.*]] = alloca i32, align 4
+; CHECK-ASAN-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[P_BYVAL]], ptr align 4 [[P]], i64 4, i1 false)
+; CHECK-ASAN-NEXT:    call void asm sideeffect "nop", ""()
+; CHECK-ASAN-NEXT:    unreachable
+;
+  call void asm sideeffect "nop", ""()
+  unreachable
+}
+
+define void @naked_function_with_tsan(ptr byval(i32) %p) sanitize_thread {
+; CHECK-TSAN-LABEL: define void @naked_function_with_tsan(
+; CHECK-TSAN-SAME: ptr byval(i32) [[P:%.*]]) #[[ATTR1:[0-9]+]] personality ptr @__gcc_personality_v0 {
+; CHECK-TSAN-NEXT:    [[TMP1:%.*]] = call ptr @llvm.returnaddress(i32 0)
+; CHECK-TSAN-NEXT:    call void @__tsan_func_entry(ptr [[TMP1]])
+; CHECK-TSAN-NEXT:    invoke void asm sideeffect "nop", ""()
+; CHECK-TSAN-NEXT:            to [[DOTNOEXC:label %.*]] unwind label %[[TSAN_CLEANUP:.*]]
+; CHECK-TSAN:       [[_NOEXC:.*:]]
+; CHECK-TSAN-NEXT:    unreachable
+; CHECK-TSAN:       [[TSAN_CLEANUP]]:
+; CHECK-TSAN-NEXT:    [[CLEANUP_LPAD:%.*]] = landingpad { ptr, i32 }
+; CHECK-TSAN-NEXT:            cleanup
+; CHECK-TSAN-NEXT:    call void @__tsan_func_exit()
+; CHECK-TSAN-NEXT:    resume { ptr, i32 } [[CLEANUP_LPAD]]
+;
+  call void asm sideeffect "nop", ""()
+  unreachable
+}
+
+define void @naked_function_with_msan(ptr byval(i32) %p) sanitize_memory {
+; CHECK-MSAN-LABEL: define void @naked_function_with_msan(
+; CHECK-MSAN-SAME: ptr byval(i32) [[P:%.*]]) #[[ATTR2:[0-9]+]] {
+; CHECK-MSAN-NEXT:    call void @llvm.donothing()
+; CHECK-MSAN-NEXT:    call void asm sideeffect "nop", ""()
+; CHECK-MSAN-NEXT:    unreachable
+;
+  call void asm sideeffect "nop", ""()
+  unreachable
+}
+
+define void @naked_function_with_hwasan(ptr byval(i32) %p) sanitize_hwaddress {
+; CHECK-HWASAN-LABEL: define void @naked_function_with_hwasan(
+; CHECK-HWASAN-SAME: ptr byval(i32) [[P:%.*]]) #[[ATTR3:[0-9]+]] {
+; CHECK-HWASAN-NEXT:    call void asm sideeffect "nop", ""()
+; CHECK-HWASAN-NEXT:    unreachable
+;
+  call void asm sideeffect "nop", ""()
+  unreachable
+}
+;.
+; CHECK-SANMD: [[META0]] = !{!"sanmd_covered2!C", [[META1:![0-9]+]]}
+; CHECK-SANMD: [[META1]] = !{i64 1}
+;.

>From 9dd4fd7c0ad24d65a71ba3244317c0a0a72705e5 Mon Sep 17 00:00:00 2001
From: Antonio Frighetto <me at antoniofrighetto.com>
Date: Sun, 15 Sep 2024 15:18:35 +0200
Subject: [PATCH 2/2] [Instrumentation] Do not request sanitizers for naked
 functions

Sanitizers instrumentation may be incompatible with naked functions,
which lack of standard prologue/epilogue.
---
 .../Instrumentation/AddressSanitizer.cpp      |  4 ++
 .../Instrumentation/HWAddressSanitizer.cpp    |  4 ++
 .../SanitizerBinaryMetadata.cpp               |  3 +
 .../Instrumentation/SanitizerCoverage.cpp     |  3 +
 llvm/test/Instrumentation/sanitizers-naked.ll | 58 ++++++-------------
 5 files changed, 31 insertions(+), 41 deletions(-)

diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index 5de0a78d087968..1e9e2d03c6ce42 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -2960,6 +2960,10 @@ bool AddressSanitizer::instrumentFunction(Function &F,
 
   bool FunctionModified = false;
 
+  // Do not apply any instrumentation for naked functions.
+  if (F.hasFnAttribute(Attribute::Naked))
+    return FunctionModified;
+
   // If needed, insert __asan_init before checking for SanitizeAddress attr.
   // This function needs to be called even if the function body is not
   // instrumented.
diff --git a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
index a7e7f9a570dac7..df645b85a9b6ec 100644
--- a/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
@@ -1598,6 +1598,10 @@ void HWAddressSanitizer::sanitizeFunction(Function &F,
   if (&F == HwasanCtorFunction)
     return;
 
+  // Do not apply any instrumentation for naked functions.
+  if (F.hasFnAttribute(Attribute::Naked))
+    return;
+
   if (!F.hasFnAttribute(Attribute::SanitizeHWAddress))
     return;
 
diff --git a/llvm/lib/Transforms/Instrumentation/SanitizerBinaryMetadata.cpp b/llvm/lib/Transforms/Instrumentation/SanitizerBinaryMetadata.cpp
index e326f30ad88eeb..eb346254f30dd7 100644
--- a/llvm/lib/Transforms/Instrumentation/SanitizerBinaryMetadata.cpp
+++ b/llvm/lib/Transforms/Instrumentation/SanitizerBinaryMetadata.cpp
@@ -258,6 +258,9 @@ bool SanitizerBinaryMetadata::run() {
 void SanitizerBinaryMetadata::runOn(Function &F, MetadataInfoSet &MIS) {
   if (F.empty())
     return;
+  // Do not apply any instrumentation for naked functions.
+  if (F.hasFnAttribute(Attribute::Naked))
+    return;
   if (F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
     return;
   if (Ignorelist && Ignorelist->inSection("metadata", "fun", F.getName()))
diff --git a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
index 6a89cee9aaf6cc..db4bf709c9cc9c 100644
--- a/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
+++ b/llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
@@ -629,6 +629,9 @@ void ModuleSanitizerCoverage::instrumentFunction(Function &F) {
     return;
   if (Blocklist && Blocklist->inSection("coverage", "fun", F.getName()))
     return;
+  // Do not apply any instrumentation for naked functions.
+  if (F.hasFnAttribute(Attribute::Naked))
+    return;
   if (F.hasFnAttribute(Attribute::NoSanitizeCoverage))
     return;
   if (F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
diff --git a/llvm/test/Instrumentation/sanitizers-naked.ll b/llvm/test/Instrumentation/sanitizers-naked.ll
index 4a28153a036e91..ef0c75500f9e44 100644
--- a/llvm/test/Instrumentation/sanitizers-naked.ll
+++ b/llvm/test/Instrumentation/sanitizers-naked.ll
@@ -11,44 +11,35 @@
 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
 target triple = "x86_64-unknown-linux-gnu"
 
-define void @naked_function(ptr byval(i32) %p) {
+define void @naked_function(ptr byval(i32) %p) naked {
 ; CHECK-ASAN-LABEL: define void @naked_function(
-; CHECK-ASAN-SAME: ptr byval(i32) [[P:%.*]]) {
+; CHECK-ASAN-SAME: ptr byval(i32) [[P:%.*]]) #[[ATTR0:[0-9]+]] {
 ; CHECK-ASAN-NEXT:    call void asm sideeffect "nop", ""()
 ; CHECK-ASAN-NEXT:    unreachable
 ;
 ; CHECK-TSAN-LABEL: define void @naked_function(
-; CHECK-TSAN-SAME: ptr byval(i32) [[P:%.*]]) personality ptr @__gcc_personality_v0 {
-; CHECK-TSAN-NEXT:    [[TMP1:%.*]] = call ptr @llvm.returnaddress(i32 0)
-; CHECK-TSAN-NEXT:    call void @__tsan_func_entry(ptr [[TMP1]])
-; CHECK-TSAN-NEXT:    invoke void asm sideeffect "nop", ""()
-; CHECK-TSAN-NEXT:            to [[DOTNOEXC:label %.*]] unwind label %[[TSAN_CLEANUP:.*]]
-; CHECK-TSAN:       [[_NOEXC:.*:]]
+; CHECK-TSAN-SAME: ptr byval(i32) [[P:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-TSAN-NEXT:    call void asm sideeffect "nop", ""()
 ; CHECK-TSAN-NEXT:    unreachable
-; CHECK-TSAN:       [[TSAN_CLEANUP]]:
-; CHECK-TSAN-NEXT:    [[CLEANUP_LPAD:%.*]] = landingpad { ptr, i32 }
-; CHECK-TSAN-NEXT:            cleanup
-; CHECK-TSAN-NEXT:    call void @__tsan_func_exit()
-; CHECK-TSAN-NEXT:    resume { ptr, i32 } [[CLEANUP_LPAD]]
 ;
 ; CHECK-MSAN-LABEL: define void @naked_function(
-; CHECK-MSAN-SAME: ptr byval(i32) [[P:%.*]]) {
+; CHECK-MSAN-SAME: ptr byval(i32) [[P:%.*]]) #[[ATTR0:[0-9]+]] {
 ; CHECK-MSAN-NEXT:    call void @llvm.donothing()
 ; CHECK-MSAN-NEXT:    call void asm sideeffect "nop", ""()
 ; CHECK-MSAN-NEXT:    unreachable
 ;
 ; CHECK-HWASAN-LABEL: define void @naked_function(
-; CHECK-HWASAN-SAME: ptr byval(i32) [[P:%.*]]) {
+; CHECK-HWASAN-SAME: ptr byval(i32) [[P:%.*]]) #[[ATTR0:[0-9]+]] {
 ; CHECK-HWASAN-NEXT:    call void asm sideeffect "nop", ""()
 ; CHECK-HWASAN-NEXT:    unreachable
 ;
 ; CHECK-SANCOV-LABEL: define void @naked_function(
-; CHECK-SANCOV-SAME: ptr byval(i32) [[P:%.*]]) {
+; CHECK-SANCOV-SAME: ptr byval(i32) [[P:%.*]]) #[[ATTR0:[0-9]+]] {
 ; CHECK-SANCOV-NEXT:    call void asm sideeffect "nop", ""()
 ; CHECK-SANCOV-NEXT:    unreachable
 ;
 ; CHECK-SANMD-LABEL: define void @naked_function(
-; CHECK-SANMD-SAME: ptr byval(i32) [[P:%.*]]) !pcsections [[META0:![0-9]+]] {
+; CHECK-SANMD-SAME: ptr byval(i32) [[P:%.*]]) #[[ATTR0:[0-9]+]] {
 ; CHECK-SANMD-NEXT:    call void asm sideeffect "nop", ""()
 ; CHECK-SANMD-NEXT:    unreachable
 ;
@@ -56,11 +47,9 @@ define void @naked_function(ptr byval(i32) %p) {
   unreachable
 }
 
-define void @naked_function_with_asan(ptr byval(i32) %p) sanitize_address {
+define void @naked_function_with_asan(ptr byval(i32) %p) sanitize_address naked {
 ; CHECK-ASAN-LABEL: define void @naked_function_with_asan(
-; CHECK-ASAN-SAME: ptr byval(i32) [[P:%.*]]) #[[ATTR0:[0-9]+]] {
-; CHECK-ASAN-NEXT:    [[P_BYVAL:%.*]] = alloca i32, align 4
-; CHECK-ASAN-NEXT:    call void @llvm.memcpy.p0.p0.i64(ptr align 4 [[P_BYVAL]], ptr align 4 [[P]], i64 4, i1 false)
+; CHECK-ASAN-SAME: ptr byval(i32) [[P:%.*]]) #[[ATTR1:[0-9]+]] {
 ; CHECK-ASAN-NEXT:    call void asm sideeffect "nop", ""()
 ; CHECK-ASAN-NEXT:    unreachable
 ;
@@ -68,28 +57,19 @@ define void @naked_function_with_asan(ptr byval(i32) %p) sanitize_address {
   unreachable
 }
 
-define void @naked_function_with_tsan(ptr byval(i32) %p) sanitize_thread {
+define void @naked_function_with_tsan(ptr byval(i32) %p) sanitize_thread naked {
 ; CHECK-TSAN-LABEL: define void @naked_function_with_tsan(
-; CHECK-TSAN-SAME: ptr byval(i32) [[P:%.*]]) #[[ATTR1:[0-9]+]] personality ptr @__gcc_personality_v0 {
-; CHECK-TSAN-NEXT:    [[TMP1:%.*]] = call ptr @llvm.returnaddress(i32 0)
-; CHECK-TSAN-NEXT:    call void @__tsan_func_entry(ptr [[TMP1]])
-; CHECK-TSAN-NEXT:    invoke void asm sideeffect "nop", ""()
-; CHECK-TSAN-NEXT:            to [[DOTNOEXC:label %.*]] unwind label %[[TSAN_CLEANUP:.*]]
-; CHECK-TSAN:       [[_NOEXC:.*:]]
+; CHECK-TSAN-SAME: ptr byval(i32) [[P:%.*]]) #[[ATTR2:[0-9]+]] {
+; CHECK-TSAN-NEXT:    call void asm sideeffect "nop", ""()
 ; CHECK-TSAN-NEXT:    unreachable
-; CHECK-TSAN:       [[TSAN_CLEANUP]]:
-; CHECK-TSAN-NEXT:    [[CLEANUP_LPAD:%.*]] = landingpad { ptr, i32 }
-; CHECK-TSAN-NEXT:            cleanup
-; CHECK-TSAN-NEXT:    call void @__tsan_func_exit()
-; CHECK-TSAN-NEXT:    resume { ptr, i32 } [[CLEANUP_LPAD]]
 ;
   call void asm sideeffect "nop", ""()
   unreachable
 }
 
-define void @naked_function_with_msan(ptr byval(i32) %p) sanitize_memory {
+define void @naked_function_with_msan(ptr byval(i32) %p) sanitize_memory naked {
 ; CHECK-MSAN-LABEL: define void @naked_function_with_msan(
-; CHECK-MSAN-SAME: ptr byval(i32) [[P:%.*]]) #[[ATTR2:[0-9]+]] {
+; CHECK-MSAN-SAME: ptr byval(i32) [[P:%.*]]) #[[ATTR3:[0-9]+]] {
 ; CHECK-MSAN-NEXT:    call void @llvm.donothing()
 ; CHECK-MSAN-NEXT:    call void asm sideeffect "nop", ""()
 ; CHECK-MSAN-NEXT:    unreachable
@@ -98,16 +78,12 @@ define void @naked_function_with_msan(ptr byval(i32) %p) sanitize_memory {
   unreachable
 }
 
-define void @naked_function_with_hwasan(ptr byval(i32) %p) sanitize_hwaddress {
+define void @naked_function_with_hwasan(ptr byval(i32) %p) sanitize_hwaddress naked {
 ; CHECK-HWASAN-LABEL: define void @naked_function_with_hwasan(
-; CHECK-HWASAN-SAME: ptr byval(i32) [[P:%.*]]) #[[ATTR3:[0-9]+]] {
+; CHECK-HWASAN-SAME: ptr byval(i32) [[P:%.*]]) #[[ATTR4:[0-9]+]] personality ptr @__hwasan_personality_thunk {
 ; CHECK-HWASAN-NEXT:    call void asm sideeffect "nop", ""()
 ; CHECK-HWASAN-NEXT:    unreachable
 ;
   call void asm sideeffect "nop", ""()
   unreachable
 }
-;.
-; CHECK-SANMD: [[META0]] = !{!"sanmd_covered2!C", [[META1:![0-9]+]]}
-; CHECK-SANMD: [[META1]] = !{i64 1}
-;.



More information about the llvm-commits mailing list