From: Vitaly Buka Date: Wed, 5 Dec 2018 01:44:31 +0000 (+0000) Subject: [asan] Add clang flag -fsanitize-address-use-odr-indicator X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=0635952db651b10442fa25b2e06573322fdd9a23;p=clang [asan] Add clang flag -fsanitize-address-use-odr-indicator Reviewers: eugenis, m.ostapenko, ygribov Subscribers: hiraditya, llvm-commits Differential Revision: https://reviews.llvm.org/D55157 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@348327 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/docs/ClangCommandLineReference.rst b/docs/ClangCommandLineReference.rst index f1b865b7eb..540c8527d2 100644 --- a/docs/ClangCommandLineReference.rst +++ b/docs/ClangCommandLineReference.rst @@ -800,6 +800,10 @@ Level of field padding for AddressSanitizer Enable linker dead stripping of globals in AddressSanitizer +.. option:: -fsanitize-address-use-odr-indicator, -fno-sanitize-address-use-odr-indicator + +Enable ODR indicator globals to avoid false ODR violation reports in partially sanitized programs at the cost of an increase in binary size + .. option:: -fsanitize-address-poison-custom-array-cookie, -fno-sanitize-address-poison-custom-array-cookie Enable "poisoning" array cookies when allocating arrays with a custom operator new\[\] in Address Sanitizer, preventing accesses to the cookies from user code. An array cookie is a small implementation-defined header added to certain array allocations to record metadata such as the length of the array. Accesses to array cookies from user code are technically allowed by the standard but are more likely to be the result of an out-of-bounds array access. diff --git a/docs/UsersManual.rst b/docs/UsersManual.rst index b24cedc5bf..e47a2e402d 100644 --- a/docs/UsersManual.rst +++ b/docs/UsersManual.rst @@ -3089,6 +3089,8 @@ Execute ``clang-cl /?`` to see a list of supported options: Level of field padding for AddressSanitizer -fsanitize-address-globals-dead-stripping Enable linker dead stripping of globals in AddressSanitizer + -fsanitize-address-use-odr-indicator + Enable ODR indicator globals to avoid false ODR violation reports in partially sanitized programs at the cost of an increase in binary size -fsanitize-address-poison-custom-array-cookie Enable poisoning array cookies when using custom operator new[] in AddressSanitizer -fsanitize-address-use-after-scope diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index daf650f0f9..e52ae219cd 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -984,6 +984,14 @@ def fno_sanitize_address_poison_custom_array_cookie def fsanitize_address_globals_dead_stripping : Flag<["-"], "fsanitize-address-globals-dead-stripping">, Group, HelpText<"Enable linker dead stripping of globals in AddressSanitizer">; +def fsanitize_address_use_odr_indicator + : Flag<["-"], "fsanitize-address-use-odr-indicator">, + Group, + HelpText<"Enable ODR indicator globals to avoid false ODR violation reports in partially sanitized programs at the cost of an increase in binary size">; +def fno_sanitize_address_use_odr_indicator + : Flag<["-"], "fno-sanitize-address-use-odr-indicator">, + Group, + HelpText<"Disable ODR indicator globals">; def fsanitize_recover : Flag<["-"], "fsanitize-recover">, Group; def fno_sanitize_recover : Flag<["-"], "fno-sanitize-recover">, Flags<[CoreOption, DriverOption]>, diff --git a/include/clang/Driver/SanitizerArgs.h b/include/clang/Driver/SanitizerArgs.h index f40b376fe5..763a187d71 100644 --- a/include/clang/Driver/SanitizerArgs.h +++ b/include/clang/Driver/SanitizerArgs.h @@ -38,6 +38,7 @@ class SanitizerArgs { bool AsanUseAfterScope = true; bool AsanPoisonCustomArrayCookie = false; bool AsanGlobalsDeadStripping = false; + bool AsanUseOdrIndicator = false; bool LinkCXXRuntimes = false; bool NeedPIE = false; bool SafeStackRuntime = false; diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def index a2fb1507ce..e531bb80ff 100644 --- a/include/clang/Frontend/CodeGenOptions.def +++ b/include/clang/Frontend/CodeGenOptions.def @@ -179,6 +179,7 @@ CODEGENOPT(SanitizeAddressPoisonCustomArrayCookie, 1, ///< global allocation function in AddressSanitizer CODEGENOPT(SanitizeAddressGlobalsDeadStripping, 1, 0) ///< Enable linker dead stripping ///< of globals in AddressSanitizer +CODEGENOPT(SanitizeAddressUseOdrIndicator, 1, 0) ///< Enable ODR indicator globals CODEGENOPT(SanitizeMemoryTrackOrigins, 2, 0) ///< Enable tracking origins in ///< MemorySanitizer CODEGENOPT(SanitizeMemoryUseAfterDtor, 1, 0) ///< Enable use-after-delete detection diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp index f746bc2f88..116678a318 100644 --- a/lib/CodeGen/BackendUtil.cpp +++ b/lib/CodeGen/BackendUtil.cpp @@ -236,11 +236,12 @@ static void addAddressSanitizerPasses(const PassManagerBuilder &Builder, const CodeGenOptions &CGOpts = BuilderWrapper.getCGOpts(); bool Recover = CGOpts.SanitizeRecover.has(SanitizerKind::Address); bool UseAfterScope = CGOpts.SanitizeAddressUseAfterScope; + bool UseOdrIndicator = CGOpts.SanitizeAddressUseOdrIndicator; bool UseGlobalsGC = asanUseGlobalsGC(T, CGOpts); PM.add(createAddressSanitizerFunctionPass(/*CompileKernel*/ false, Recover, UseAfterScope)); PM.add(createAddressSanitizerModulePass(/*CompileKernel*/ false, Recover, - UseGlobalsGC)); + UseGlobalsGC, UseOdrIndicator)); } static void addKernelAddressSanitizerPasses(const PassManagerBuilder &Builder, @@ -248,7 +249,8 @@ static void addKernelAddressSanitizerPasses(const PassManagerBuilder &Builder, PM.add(createAddressSanitizerFunctionPass( /*CompileKernel*/ true, /*Recover*/ true, /*UseAfterScope*/ false)); PM.add(createAddressSanitizerModulePass( - /*CompileKernel*/ true, /*Recover*/ true)); + /*CompileKernel*/ true, /*Recover*/ true, /*UseGlobalsGC*/ true, + /*UseOdrIndicator*/ false)); } static void addHWAddressSanitizerPasses(const PassManagerBuilder &Builder, diff --git a/lib/Driver/SanitizerArgs.cpp b/lib/Driver/SanitizerArgs.cpp index fe71b6c85c..4e0d7491bb 100644 --- a/lib/Driver/SanitizerArgs.cpp +++ b/lib/Driver/SanitizerArgs.cpp @@ -732,6 +732,11 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, AsanGlobalsDeadStripping = !TC.getTriple().isOSBinFormatELF() || TC.getTriple().isOSFuchsia() || Args.hasArg(options::OPT_fsanitize_address_globals_dead_stripping); + + AsanUseOdrIndicator = + Args.hasFlag(options::OPT_fsanitize_address_use_odr_indicator, + options::OPT_fno_sanitize_address_use_odr_indicator, + AsanUseOdrIndicator); } else { AsanUseAfterScope = false; } @@ -905,6 +910,9 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args, if (AsanGlobalsDeadStripping) CmdArgs.push_back("-fsanitize-address-globals-dead-stripping"); + if (AsanUseOdrIndicator) + CmdArgs.push_back("-fsanitize-address-use-odr-indicator"); + // MSan: Workaround for PR16386. // ASan: This is mainly to help LSan with cases such as // https://github.com/google/sanitizers/issues/373 diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 74b39cea54..1d48863393 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -1115,6 +1115,11 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, } Opts.SanitizeAddressGlobalsDeadStripping = Args.hasArg(OPT_fsanitize_address_globals_dead_stripping); + if (Arg *A = Args.getLastArg(OPT_fsanitize_address_use_odr_indicator, + OPT_fno_sanitize_address_use_odr_indicator)) { + Opts.SanitizeAddressUseOdrIndicator = + A->getOption().getID() == OPT_fsanitize_address_use_odr_indicator; + } Opts.SSPBufferSize = getLastArgIntValue(Args, OPT_stack_protector_buffer_size, 8, Diags); Opts.StackRealignment = Args.hasArg(OPT_mstackrealign); diff --git a/test/CodeGen/asan-globals-odr.cpp b/test/CodeGen/asan-globals-odr.cpp new file mode 100644 index 0000000000..4a148c3ce3 --- /dev/null +++ b/test/CodeGen/asan-globals-odr.cpp @@ -0,0 +1,30 @@ +// RUN: %clang_cc1 -fsanitize=address -emit-llvm -o - -triple x86_64-linux %s | FileCheck %s --check-prefixes=CHECK,INDICATOR0,GLOB_VAR,ALIAS0 +// RUN: %clang_cc1 -fsanitize=address -fsanitize-address-use-odr-indicator -emit-llvm -o - -triple x86_64-linux %s | FileCheck %s --check-prefixes=CHECK,INDICATOR1,GLOB_ALIAS_INDICATOR,ALIAS1 +// RUN: %clang_cc1 -fsanitize=address -fno-sanitize-address-use-odr-indicator -emit-llvm -o - -triple x86_64-linux %s | FileCheck %s --check-prefixes=CHECK,INDICATOR0,GLOB_VAR,ALIAS0 +// RUN: %clang_cc1 -fsanitize=address -fno-sanitize-address-use-odr-indicator -fsanitize-address-use-odr-indicator -emit-llvm -o - -triple x86_64-linux %s | FileCheck %s --check-prefixes=CHECK,INDICATOR1,GLOB_ALIAS_INDICATOR,ALIAS1 +// RUN: %clang_cc1 -fsanitize=address -fsanitize-address-use-odr-indicator -fno-sanitize-address-use-odr-indicator -emit-llvm -o - -triple x86_64-linux %s | FileCheck %s --check-prefixes=CHECK,INDICATOR0,GLOB_VAR,ALIAS0 + +// No alias on Windows but indicators should work. +// RUN: %clang_cc1 -fsanitize=address -emit-llvm -o - -triple x86_64-windows-msvc %s | FileCheck %s --check-prefixes=CHECK,GLOB_VAR,ALIAS0 +// RUN: %clang_cc1 -fsanitize=address -fsanitize-address-use-odr-indicator -emit-llvm -o - -triple x86_64-windows-msvc %s | FileCheck %s --check-prefixes=CHECK,INDICATOR1,GLOB_VAR_INDICATOR,ALIAS0 + +int global; + +int main() { + return global; +} + +// CHECK: [[VAR:@.*global.*]] ={{.*}} global { i32, [60 x i8] } zeroinitializer, align 32 + +// INDICATOR0-NOT: __odr_asan_gen +// INDICATOR1: [[ODR:@.*__odr_asan_gen_.*global.*]] = global i8 0, align 1 + +// GLOB_VAR: @0 = internal global {{.*}} [[VAR]] to i64), {{.*}}, i64 0 }] +// GLOB_VAR_INDICATOR: @0 = internal global {{.*}} [[VAR]] to i64), {{.*}}, i64 ptrtoint (i8* [[ODR]] to i64) }] +// GLOB_ALIAS_INDICATOR: @0 = internal global {{.*}} @1 to i64), {{.*}}, i64 ptrtoint (i8* [[ODR]] to i64) }] + +// ALIAS0-NOT: private alias +// ALIAS1: @1 = private alias {{.*}} [[VAR]] + +// CHECK: call void @__asan_register_globals(i64 ptrtoint ([1 x { i64, i64, i64, i64, i64, i64, i64, i64 }]* @0 to i64), i64 1) +// CHECK: call void @__asan_unregister_globals(i64 ptrtoint ([1 x { i64, i64, i64, i64, i64, i64, i64, i64 }]* @0 to i64), i64 1) diff --git a/test/Driver/fsanitize.c b/test/Driver/fsanitize.c index aeb0130e8c..9411b68dab 100644 --- a/test/Driver/fsanitize.c +++ b/test/Driver/fsanitize.c @@ -248,6 +248,24 @@ // CHECK-ASAN-GLOBALS: -cc1{{.*}}-fsanitize-address-globals-dead-stripping // CHECK-NO-ASAN-GLOBALS-NOT: -cc1{{.*}}-fsanitize-address-globals-dead-stripping +// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-address-use-odr-indicator %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-ODR-INDICATOR +// RUN: %clang_cl --target=x86_64-windows -fsanitize=address -fsanitize-address-use-odr-indicator -### -- %s 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-ODR-INDICATOR +// CHECK-ASAN-ODR-INDICATOR: -cc1{{.*}}-fsanitize-address-use-odr-indicator + +// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fno-sanitize-address-use-odr-indicator %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-ODR-INDICATOR-OFF +// RUN: %clang_cl --target=x86_64-windows -fsanitize=address -fno-sanitize-address-use-odr-indicator -### -- %s 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-ODR-INDICATOR-OFF +// CHECK-ASAN-ODR-INDICATOR-OFF-NOT: -cc1{{.*}}address-generate-odr-globals + +// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fno-sanitize-address-use-odr-indicator -fsanitize-address-use-odr-indicator %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-ODR-INDICATOR-BOTH +// RUN: %clang_cl --target=x86_64-windows -fsanitize=address -fno-sanitize-address-use-odr-indicator -fsanitize-address-use-odr-indicator -### -- %s 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-ODR-INDICATOR-BOTH +// CHECK-ASAN-ODR-INDICATOR-BOTH: -cc1{{.*}}-fsanitize-address-use-odr-indicator + +// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-address-use-odr-indicator -fno-sanitize-address-use-odr-indicator %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-ODR-INDICATOR-BOTH-OFF +// CHECK-ASAN-ODR-INDICATOR-BOTH-OFF-NOT: -cc1{{.*}}address-generate-odr-globals + +// RUN: %clang -target x86_64-linux-gnu -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-WITHOUT-ODR-INDICATOR +// CHECK-ASAN-WITHOUT-ODR-INDICATOR-NOT: -cc1{{.*}}address-generate-odr-globals + // RUN: %clang -target x86_64-linux-gnu -fsanitize-memory-track-origins -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ONLY-TRACK-ORIGINS // CHECK-ONLY-TRACK-ORIGINS: warning: argument unused during compilation: '-fsanitize-memory-track-origins'