Skip to content

Commit

Permalink
[Instrumentation] Do not request sanitizers for naked functions
Browse files Browse the repository at this point in the history
Sanitizers instrumentation may be incompatible with naked functions,
which lack of standard prologue/epilogue.
  • Loading branch information
antoniofrighetto committed Sep 17, 2024
1 parent 539f916 commit 4896ae9
Show file tree
Hide file tree
Showing 5 changed files with 31 additions and 41 deletions.
4 changes: 4 additions & 0 deletions llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 4 additions & 0 deletions llvm/lib/Transforms/Instrumentation/HWAddressSanitizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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()))
Expand Down
3 changes: 3 additions & 0 deletions llvm/lib/Transforms/Instrumentation/SanitizerCoverage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down
58 changes: 17 additions & 41 deletions llvm/test/Instrumentation/sanitizers-naked.ll
Original file line number Diff line number Diff line change
Expand Up @@ -11,85 +11,65 @@
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
;
call void asm sideeffect "nop", ""()
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
;
call void asm sideeffect "nop", ""()
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
Expand All @@ -98,18 +78,14 @@ 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}
;.
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
; CHECK: {{.*}}

0 comments on commit 4896ae9

Please sign in to comment.