forked from OSchip/llvm-project
[asan] Add support for disable_sanitizer_instrumentation attribute
For ASan this will effectively serve as a synonym for __attribute__((no_sanitize("address"))) Differential Revision: https://reviews.llvm.org/D114421
This commit is contained in:
parent
b618880e7b
commit
2b554920f1
|
@ -229,6 +229,12 @@ compilers, so we suggest to use it together with
|
|||
The same attribute used on a global variable prevents AddressSanitizer
|
||||
from adding redzones around it and detecting out of bounds accesses.
|
||||
|
||||
|
||||
AddressSanitizer also supports
|
||||
``__attribute__((disable_sanitizer_instrumentation))``. This attribute
|
||||
works similar to ``__attribute__((no_sanitize("address")))``, but it also
|
||||
prevents instrumentation performed by other sanitizers.
|
||||
|
||||
Suppressing Errors in Recompiled Code (Ignorelist)
|
||||
--------------------------------------------------
|
||||
|
||||
|
|
|
@ -382,9 +382,6 @@ void CodeGenFunction::FinishFunction(SourceLocation EndLoc) {
|
|||
"__cyg_profile_func_exit");
|
||||
}
|
||||
|
||||
if (ShouldSkipSanitizerInstrumentation())
|
||||
CurFn->addFnAttr(llvm::Attribute::DisableSanitizerInstrumentation);
|
||||
|
||||
// Emit debug descriptor for function end.
|
||||
if (CGDebugInfo *DI = getDebugInfo())
|
||||
DI->EmitFunctionEnd(Builder, CurFn);
|
||||
|
@ -766,17 +763,22 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, QualType RetTy,
|
|||
Fn->addFnAttr(llvm::Attribute::NoSanitizeCoverage);
|
||||
}
|
||||
|
||||
// Apply sanitizer attributes to the function.
|
||||
if (SanOpts.hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress))
|
||||
Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
|
||||
if (SanOpts.hasOneOf(SanitizerKind::HWAddress | SanitizerKind::KernelHWAddress))
|
||||
Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);
|
||||
if (SanOpts.has(SanitizerKind::MemTag))
|
||||
Fn->addFnAttr(llvm::Attribute::SanitizeMemTag);
|
||||
if (SanOpts.has(SanitizerKind::Thread))
|
||||
Fn->addFnAttr(llvm::Attribute::SanitizeThread);
|
||||
if (SanOpts.hasOneOf(SanitizerKind::Memory | SanitizerKind::KernelMemory))
|
||||
Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
|
||||
if (ShouldSkipSanitizerInstrumentation()) {
|
||||
CurFn->addFnAttr(llvm::Attribute::DisableSanitizerInstrumentation);
|
||||
} else {
|
||||
// Apply sanitizer attributes to the function.
|
||||
if (SanOpts.hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress))
|
||||
Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
|
||||
if (SanOpts.hasOneOf(SanitizerKind::HWAddress |
|
||||
SanitizerKind::KernelHWAddress))
|
||||
Fn->addFnAttr(llvm::Attribute::SanitizeHWAddress);
|
||||
if (SanOpts.has(SanitizerKind::MemTag))
|
||||
Fn->addFnAttr(llvm::Attribute::SanitizeMemTag);
|
||||
if (SanOpts.has(SanitizerKind::Thread))
|
||||
Fn->addFnAttr(llvm::Attribute::SanitizeThread);
|
||||
if (SanOpts.hasOneOf(SanitizerKind::Memory | SanitizerKind::KernelMemory))
|
||||
Fn->addFnAttr(llvm::Attribute::SanitizeMemory);
|
||||
}
|
||||
if (SanOpts.has(SanitizerKind::SafeStack))
|
||||
Fn->addFnAttr(llvm::Attribute::SafeStack);
|
||||
if (SanOpts.has(SanitizerKind::ShadowCallStack))
|
||||
|
|
|
@ -73,6 +73,8 @@ void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV,
|
|||
for (auto Attr : D.specific_attrs<NoSanitizeAttr>())
|
||||
if (Attr->getMask() & SanitizerKind::Address)
|
||||
IsExcluded = true;
|
||||
if (D.hasAttr<DisableSanitizerInstrumentationAttr>())
|
||||
IsExcluded = true;
|
||||
reportGlobalToASan(GV, D.getLocation(), OS.str(), D.getType(), IsDynInit,
|
||||
IsExcluded);
|
||||
}
|
||||
|
|
|
@ -73,3 +73,12 @@ __attribute__((no_sanitize("kernel-hwaddress"))) int NoSanitizeKernelHWAddress()
|
|||
// CHECK-KASAN: {{Function Attrs: mustprogress noinline nounwind sanitize_address$}}
|
||||
// CHECK-HWASAN: {{Function Attrs: mustprogress noinline nounwind$}}
|
||||
// CHECK-KHWASAN: {{Function Attrs: mustprogress noinline nounwind$}}
|
||||
|
||||
__attribute__((disable_sanitizer_instrumentation)) int DisableSanitizerInstrumentation() {
|
||||
return 0;
|
||||
}
|
||||
// CHECK-NOASAN: {{Function Attrs: disable_sanitizer_instrumentation mustprogress noinline nounwind$}}
|
||||
// CHECK-ASAN: {{Function Attrs: disable_sanitizer_instrumentation mustprogress noinline nounwind$}}
|
||||
// CHECK-KASAN: {{Function Attrs: disable_sanitizer_instrumentation mustprogress noinline nounwind$}}
|
||||
// CHECK-HWASAN: {{Function Attrs: disable_sanitizer_instrumentation mustprogress noinline nounwind$}}
|
||||
// CHECK-KHWASAN: {{Function Attrs: disable_sanitizer_instrumentation mustprogress noinline nounwind$}}
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
int global;
|
||||
int dyn_init_global = global;
|
||||
int __attribute__((no_sanitize("address"))) attributed_global;
|
||||
int __attribute__((disable_sanitizer_instrumentation)) disable_instrumentation_global;
|
||||
int ignorelisted_global;
|
||||
|
||||
int __attribute__((section("__DATA, __common"))) sectioned_global; // KASAN - ignore globals in a section
|
||||
|
@ -50,31 +51,33 @@ void func() {
|
|||
// UWTABLE: attributes #[[#ATTR]] = { nounwind uwtable }
|
||||
// UWTABLE: ![[#]] = !{i32 7, !"uwtable", i32 1}
|
||||
|
||||
// CHECK: !llvm.asan.globals = !{![[EXTRA_GLOBAL:[0-9]+]], ![[GLOBAL:[0-9]+]], ![[DYN_INIT_GLOBAL:[0-9]+]], ![[ATTR_GLOBAL:[0-9]+]], ![[IGNORELISTED_GLOBAL:[0-9]+]], ![[SECTIONED_GLOBAL:[0-9]+]], ![[SPECIAL_GLOBAL:[0-9]+]], ![[STATIC_VAR:[0-9]+]], ![[LITERAL:[0-9]+]]}
|
||||
// CHECK: !llvm.asan.globals = !{![[EXTRA_GLOBAL:[0-9]+]], ![[GLOBAL:[0-9]+]], ![[DYN_INIT_GLOBAL:[0-9]+]], ![[ATTR_GLOBAL:[0-9]+]], ![[DISABLE_INSTR_GLOBAL:[0-9]+]], ![[IGNORELISTED_GLOBAL:[0-9]+]], ![[SECTIONED_GLOBAL:[0-9]+]], ![[SPECIAL_GLOBAL:[0-9]+]], ![[STATIC_VAR:[0-9]+]], ![[LITERAL:[0-9]+]]}
|
||||
// CHECK: ![[EXTRA_GLOBAL]] = !{{{.*}} ![[EXTRA_GLOBAL_LOC:[0-9]+]], !"extra_global", i1 false, i1 false}
|
||||
// CHECK: ![[EXTRA_GLOBAL_LOC]] = !{!"{{.*}}extra-source.cpp", i32 1, i32 5}
|
||||
// CHECK: ![[GLOBAL]] = !{{{.*}} ![[GLOBAL_LOC:[0-9]+]], !"global", i1 false, i1 false}
|
||||
// CHECK: ![[GLOBAL_LOC]] = !{!"{{.*}}asan-globals.cpp", i32 10, i32 5}
|
||||
// CHECK: ![[DYN_INIT_GLOBAL]] = !{{{.*}} ![[DYN_INIT_LOC:[0-9]+]], !"dyn_init_global", i1 true, i1 false}
|
||||
// CHECK: ![[DYN_INIT_LOC]] = !{!"{{.*}}asan-globals.cpp", i32 11, i32 5}
|
||||
// CHECK: ![[ATTR_GLOBAL]] = !{{{.*}}, null, null, i1 false, i1 true}
|
||||
// CHECK: ![[IGNORELISTED_GLOBAL]] = !{{{.*}}, null, null, i1 false, i1 true}
|
||||
// CHECK: ![[ATTR_GLOBAL]] = !{{{.*attributed_global.*}}, null, null, i1 false, i1 true}
|
||||
// CHECK: ![[DISABLE_INSTR_GLOBAL]] = !{{{.*disable_instrumentation_global.*}}, null, null, i1 false, i1 true}
|
||||
// CHECK: ![[IGNORELISTED_GLOBAL]] = !{{{.*ignorelisted_global.*}}, null, null, i1 false, i1 true}
|
||||
// CHECK: ![[SECTIONED_GLOBAL]] = !{{{.*}} ![[SECTIONED_GLOBAL_LOC:[0-9]+]], !"sectioned_global", i1 false, i1 false}
|
||||
// CHECK: ![[SECTIONED_GLOBAL_LOC]] = !{!"{{.*}}asan-globals.cpp", i32 15, i32 50}
|
||||
// CHECK: ![[SECTIONED_GLOBAL_LOC]] = !{!"{{.*}}asan-globals.cpp", i32 16, i32 50}
|
||||
// CHECK: ![[SPECIAL_GLOBAL]] = !{{{.*}} ![[SPECIAL_GLOBAL_LOC:[0-9]+]], !"__special_global", i1 false, i1 false}
|
||||
// CHECK: ![[SPECIAL_GLOBAL_LOC]] = !{!"{{.*}}asan-globals.cpp", i32 17, i32 5}
|
||||
// CHECK: ![[SPECIAL_GLOBAL_LOC]] = !{!"{{.*}}asan-globals.cpp", i32 18, i32 5}
|
||||
// CHECK: ![[STATIC_VAR]] = !{{{.*}} ![[STATIC_LOC:[0-9]+]], !"static_var", i1 false, i1 false}
|
||||
// CHECK: ![[STATIC_LOC]] = !{!"{{.*}}asan-globals.cpp", i32 21, i32 14}
|
||||
// CHECK: ![[STATIC_LOC]] = !{!"{{.*}}asan-globals.cpp", i32 22, i32 14}
|
||||
// CHECK: ![[LITERAL]] = !{{{.*}} ![[LITERAL_LOC:[0-9]+]], !"<string literal>", i1 false, i1 false}
|
||||
// CHECK: ![[LITERAL_LOC]] = !{!"{{.*}}asan-globals.cpp", i32 22, i32 25}
|
||||
// CHECK: ![[LITERAL_LOC]] = !{!"{{.*}}asan-globals.cpp", i32 23, i32 25}
|
||||
|
||||
// IGNORELIST-SRC: !llvm.asan.globals = !{![[EXTRA_GLOBAL:[0-9]+]], ![[GLOBAL:[0-9]+]], ![[DYN_INIT_GLOBAL:[0-9]+]], ![[ATTR_GLOBAL:[0-9]+]], ![[IGNORELISTED_GLOBAL:[0-9]+]], ![[SECTIONED_GLOBAL:[0-9]+]], ![[SPECIAL_GLOBAL:[0-9]+]], ![[STATIC_VAR:[0-9]+]], ![[LITERAL:[0-9]+]]}
|
||||
// IGNORELIST-SRC: !llvm.asan.globals = !{![[EXTRA_GLOBAL:[0-9]+]], ![[GLOBAL:[0-9]+]], ![[DYN_INIT_GLOBAL:[0-9]+]], ![[ATTR_GLOBAL:[0-9]+]], ![[DISABLE_INSTR_GLOBAL:[0-9]+]], ![[IGNORELISTED_GLOBAL:[0-9]+]], ![[SECTIONED_GLOBAL:[0-9]+]], ![[SPECIAL_GLOBAL:[0-9]+]], ![[STATIC_VAR:[0-9]+]], ![[LITERAL:[0-9]+]]}
|
||||
// IGNORELIST-SRC: ![[EXTRA_GLOBAL]] = !{{{.*}} ![[EXTRA_GLOBAL_LOC:[0-9]+]], !"extra_global", i1 false, i1 false}
|
||||
// IGNORELIST-SRC: ![[EXTRA_GLOBAL_LOC]] = !{!"{{.*}}extra-source.cpp", i32 1, i32 5}
|
||||
// IGNORELIST-SRC: ![[GLOBAL]] = !{{{.*}} null, null, i1 false, i1 true}
|
||||
// IGNORELIST-SRC: ![[DYN_INIT_GLOBAL]] = !{{{.*}} null, null, i1 true, i1 true}
|
||||
// IGNORELIST-SRC: ![[ATTR_GLOBAL]] = !{{{.*}}, null, null, i1 false, i1 true}
|
||||
// IGNORELIST-SRC: ![[IGNORELISTED_GLOBAL]] = !{{{.*}}, null, null, i1 false, i1 true}
|
||||
// IGNORELIST-SRC: ![[ATTR_GLOBAL]] = !{{{.*attributed_global.*}}, null, null, i1 false, i1 true}
|
||||
// IGNORELIST-SRC: ![[DISABLE_INSTR_GLOBAL]] = !{{{.*disable_instrumentation_global.*}}, null, null, i1 false, i1 true}
|
||||
// IGNORELIST-SRC: ![[IGNORELISTED_GLOBAL]] = !{{{.*ignorelisted_global.*}}, null, null, i1 false, i1 true}
|
||||
// IGNORELIST-SRC: ![[SECTIONED_GLOBAL]] = !{{{.*}} null, null, i1 false, i1 true}
|
||||
// IGNORELIST-SRC: ![[SPECIAL_GLOBAL]] = !{{{.*}} null, null, i1 false, i1 true}
|
||||
// IGNORELIST-SRC: ![[STATIC_VAR]] = !{{{.*}} null, null, i1 false, i1 true}
|
||||
|
|
|
@ -2890,6 +2890,9 @@ bool AddressSanitizer::instrumentFunction(Function &F,
|
|||
// Leave if the function doesn't need instrumentation.
|
||||
if (!F.hasFnAttribute(Attribute::SanitizeAddress)) return FunctionModified;
|
||||
|
||||
if (F.hasFnAttribute(Attribute::DisableSanitizerInstrumentation))
|
||||
return FunctionModified;
|
||||
|
||||
LLVM_DEBUG(dbgs() << "ASAN instrumenting:\n" << F << "\n");
|
||||
|
||||
initializeCallbacks(*F.getParent());
|
||||
|
|
|
@ -0,0 +1,47 @@
|
|||
; This test checks that we are not instrumenting sanitizer code.
|
||||
; RUN: opt < %s -passes='asan-pipeline' -S | FileCheck %s
|
||||
|
||||
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
||||
target triple = "x86_64-unknown-linux-gnu"
|
||||
|
||||
; Function with sanitize_address is instrumented.
|
||||
; Function Attrs: nounwind uwtable
|
||||
define void @instr_sa(i32* %a) sanitize_address {
|
||||
entry:
|
||||
%tmp1 = load i32, i32* %a, align 4
|
||||
%tmp2 = add i32 %tmp1, 1
|
||||
store i32 %tmp2, i32* %a, align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @instr_sa
|
||||
; CHECK: call void @__asan_report_load
|
||||
|
||||
|
||||
; Function with disable_sanitizer_instrumentation is not instrumented.
|
||||
; Function Attrs: nounwind uwtable
|
||||
define void @noinstr_dsi(i32* %a) disable_sanitizer_instrumentation {
|
||||
entry:
|
||||
%tmp1 = load i32, i32* %a, align 4
|
||||
%tmp2 = add i32 %tmp1, 1
|
||||
store i32 %tmp2, i32* %a, align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @noinstr_dsi
|
||||
; CHECK-NOT: call void @__asan_report_load
|
||||
|
||||
|
||||
; disable_sanitizer_instrumentation takes precedence over sanitize_address.
|
||||
; Function Attrs: nounwind uwtable
|
||||
define void @noinstr_dsi_sa(i32* %a) disable_sanitizer_instrumentation sanitize_address {
|
||||
entry:
|
||||
%tmp1 = load i32, i32* %a, align 4
|
||||
%tmp2 = add i32 %tmp1, 1
|
||||
store i32 %tmp2, i32* %a, align 4
|
||||
ret void
|
||||
}
|
||||
|
||||
; CHECK-LABEL: @noinstr_dsi_sa
|
||||
; CHECK-NOT: call void @__asan_report_load
|
||||
|
Loading…
Reference in New Issue