[llvm] [Instrumentation] Do not run sanitizers for naked functions (PR #108552)
Antonio Frighetto via llvm-commits
llvm-commits at lists.llvm.org
Fri Sep 13 05:37:28 PDT 2024
https://github.com/antoniofrighetto created https://github.com/llvm/llvm-project/pull/108552
Sanitizers instrumentation is incompatible with naked functions, which are expected to contain only inline asm.
>From d76f9d742084bfb8b10a73a35864687934df9005 Mon Sep 17 00:00:00 2001
From: Antonio Frighetto <me at antoniofrighetto.com>
Date: Fri, 13 Sep 2024 12:16:25 +0200
Subject: [PATCH] [Instrumentation] Do not run sanitizers for naked functions
Sanitizers instrumentation is incompatible with naked functions,
which are expected to contain only inline asm.
---
.../Instrumentation/AddressSanitizer.cpp | 4 ++
.../Instrumentation/DataFlowSanitizer.cpp | 3 +-
.../Instrumentation/MemorySanitizer.cpp | 4 ++
.../SanitizerBinaryMetadata.cpp | 3 ++
.../Instrumentation/SanitizerCoverage.cpp | 3 ++
.../Instrumentation/sanitizers-no-naked.ll | 49 +++++++++++++++++++
6 files changed, 65 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/Instrumentation/sanitizers-no-naked.ll
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/DataFlowSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
index b4b5f67d2e62da..1cb579309089e1 100644
--- a/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/DataFlowSanitizer.cpp
@@ -1545,8 +1545,9 @@ bool DataFlowSanitizer::runImpl(
SmallPtrSet<Function *, 2> FnsWithForceZeroLabel;
SmallPtrSet<Constant *, 1> PersonalityFns;
for (Function &F : M)
+ // Do not apply any instrumentation for naked functions or if disabled.
if (!F.isIntrinsic() && !DFSanRuntimeFunctions.contains(&F) &&
- !LibAtomicFunction(F) &&
+ !LibAtomicFunction(F) && !F.hasFnAttribute(Attribute::Naked) &&
!F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation)) {
FnsToInstrument.push_back(&F);
if (F.hasPersonalityFn())
diff --git a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
index 17c5638cf8ced7..90de58143955c3 100644
--- a/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/MemorySanitizer.cpp
@@ -6078,6 +6078,10 @@ bool MemorySanitizer::sanitizeFunction(Function &F, TargetLibraryInfo &TLI) {
if (!CompileKernel && F.getName() == kMsanModuleCtorName)
return false;
+ // Do not apply any instrumentation for naked functions.
+ if (F.hasFnAttribute(Attribute::Naked))
+ return false;
+
if (F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
return false;
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-no-naked.ll b/llvm/test/Instrumentation/sanitizers-no-naked.ll
new file mode 100644
index 00000000000000..72a78d9f1a33e5
--- /dev/null
+++ b/llvm/test/Instrumentation/sanitizers-no-naked.ll
@@ -0,0 +1,49 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=asan -S | FileCheck %s
+; RUN: opt < %s -passes=tsan -S | FileCheck %s
+; RUN: opt < %s -passes=dfsan -dfsan-track-origins=1 -S | FileCheck %s
+; RUN: opt < %s -passes='module(sancov-module)' -sanitizer-coverage-level=3 -sanitizer-coverage-control-flow -S | FileCheck %s
+; RUN: opt < %s -passes='module(sanmd-module)' -sanitizer-metadata-atomics -S | FileCheck %s
+
+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() naked {
+; CHECK-LABEL: define void @naked_function(
+; CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: call void asm sideeffect "nop", ""()
+; CHECK-NEXT: unreachable
+;
+ call void asm sideeffect "nop", ""()
+ unreachable
+}
+
+define void @naked_function_with_asan() sanitize_address naked {
+; CHECK-LABEL: define void @naked_function_with_asan(
+; CHECK-SAME: ) #[[ATTR1:[0-9]+]] {
+; CHECK-NEXT: call void asm sideeffect "nop", ""()
+; CHECK-NEXT: unreachable
+;
+ call void asm sideeffect "nop", ""()
+ unreachable
+}
+
+define void @naked_function_with_tsan() sanitize_thread naked {
+; CHECK-LABEL: define void @naked_function_with_tsan(
+; CHECK-SAME: ) #[[ATTR2:[0-9]+]] {
+; CHECK-NEXT: call void asm sideeffect "nop", ""()
+; CHECK-NEXT: unreachable
+;
+ call void asm sideeffect "nop", ""()
+ unreachable
+}
+
+define void @naked_function_with_msan() sanitize_memory naked {
+; CHECK-LABEL: define void @naked_function_with_msan(
+; CHECK-SAME: ) #[[ATTR3:[0-9]+]] {
+; CHECK-NEXT: call void asm sideeffect "nop", ""()
+; CHECK-NEXT: unreachable
+;
+ call void asm sideeffect "nop", ""()
+ unreachable
+}
More information about the llvm-commits
mailing list