[clang] e0b469f - [clang-cl][sanitizer] Add -fsanitize-address-use-after-return to clang.
Kevin Athey via cfe-commits
cfe-commits at lists.llvm.org
Fri Jun 11 12:07:46 PDT 2021
Author: Kevin Athey
Date: 2021-06-11T12:07:35-07:00
New Revision: e0b469ffa142353fc90bfc6eadb638a805ebed75
URL: https://github.com/llvm/llvm-project/commit/e0b469ffa142353fc90bfc6eadb638a805ebed75
DIFF: https://github.com/llvm/llvm-project/commit/e0b469ffa142353fc90bfc6eadb638a805ebed75.diff
LOG: [clang-cl][sanitizer] Add -fsanitize-address-use-after-return to clang.
Also:
- add driver test (fsanitize-use-after-return.c)
- add basic IR test (asan-use-after-return.cpp)
- (NFC) cleaned up logic for generating table of __asan_stack_malloc
depending on flag.
for issue: https://github.com/google/sanitizers/issues/1394
Reviewed By: vitalybuka
Differential Revision: https://reviews.llvm.org/D104076
Added:
clang/test/CodeGen/asan-use-after-return.cpp
clang/test/Driver/fsanitize-use-after-return.c
Modified:
clang/include/clang/Basic/CodeGenOptions.def
clang/include/clang/Basic/Sanitizers.h
clang/include/clang/Driver/Options.td
clang/include/clang/Driver/SanitizerArgs.h
clang/lib/Basic/Sanitizers.cpp
clang/lib/CodeGen/BackendUtil.cpp
clang/lib/Driver/SanitizerArgs.cpp
clang/test/Driver/cl-options.c
llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h
llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
Removed:
################################################################################
diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def
index b4699805eb40..e3202cf88756 100644
--- a/clang/include/clang/Basic/CodeGenOptions.def
+++ b/clang/include/clang/Basic/CodeGenOptions.def
@@ -212,6 +212,10 @@ CODEGENOPT(NewStructPathTBAA , 1, 0) ///< Whether or not to use enhanced struct-
CODEGENOPT(SaveTempLabels , 1, 0) ///< Save temporary labels.
CODEGENOPT(SanitizeAddressUseAfterScope , 1, 0) ///< Enable use-after-scope detection
///< in AddressSanitizer
+ENUM_CODEGENOPT(SanitizeAddressUseAfterReturn,
+ llvm::AsanDetectStackUseAfterReturnMode, 2,
+ llvm::AsanDetectStackUseAfterReturnMode::Runtime
+ ) ///< Set detection mode for stack-use-after-return.
CODEGENOPT(SanitizeAddressPoisonCustomArrayCookie, 1,
0) ///< Enable poisoning operator new[] which is not a replaceable
///< global allocation function in AddressSanitizer
diff --git a/clang/include/clang/Basic/Sanitizers.h b/clang/include/clang/Basic/Sanitizers.h
index 82e5a73dee2e..b12a3b7821d7 100644
--- a/clang/include/clang/Basic/Sanitizers.h
+++ b/clang/include/clang/Basic/Sanitizers.h
@@ -192,6 +192,12 @@ StringRef AsanDtorKindToString(llvm::AsanDtorKind kind);
llvm::AsanDtorKind AsanDtorKindFromString(StringRef kind);
+StringRef AsanDetectStackUseAfterReturnModeToString(
+ llvm::AsanDetectStackUseAfterReturnMode mode);
+
+llvm::AsanDetectStackUseAfterReturnMode
+AsanDetectStackUseAfterReturnModeFromString(StringRef modeStr);
+
} // namespace clang
#endif // LLVM_CLANG_BASIC_SANITIZERS_H
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 6f3169644396..3968aa3431ea 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -1587,6 +1587,16 @@ defm sanitize_address_use_after_scope : BoolOption<"f", "sanitize-address-use-af
PosFlag<SetTrue, [], "Enable">, NegFlag<SetFalse, [CoreOption, NoXarchOption], "Disable">,
BothFlags<[], " use-after-scope detection in AddressSanitizer">>,
Group<f_clang_Group>;
+def sanitize_address_use_after_return_EQ
+ : Joined<["-"], "fsanitize-address-use-after-return=">,
+ MetaVarName<"<mode>">,
+ Flags<[CC1Option]>,
+ HelpText<"Select the mode of detecting stack use-after-return in AddressSanitizer">,
+ Group<f_clang_Group>,
+ Values<"never,runtime,always">,
+ NormalizedValuesScope<"llvm::AsanDetectStackUseAfterReturnMode">,
+ NormalizedValues<["Never", "Runtime", "Always"]>,
+ MarshallingInfoEnum<CodeGenOpts<"SanitizeAddressUseAfterReturn">, "Runtime">;
defm sanitize_address_poison_custom_array_cookie : BoolOption<"f", "sanitize-address-poison-custom-array-cookie",
CodeGenOpts<"SanitizeAddressPoisonCustomArrayCookie">, DefaultFalse,
PosFlag<SetTrue, [], "Enable">, NegFlag<SetFalse, [], "Disable">,
diff --git a/clang/include/clang/Driver/SanitizerArgs.h b/clang/include/clang/Driver/SanitizerArgs.h
index adfc26382f60..63a195fdf753 100644
--- a/clang/include/clang/Driver/SanitizerArgs.h
+++ b/clang/include/clang/Driver/SanitizerArgs.h
@@ -12,6 +12,7 @@
#include "clang/Driver/Types.h"
#include "llvm/Option/Arg.h"
#include "llvm/Option/ArgList.h"
+#include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h"
#include <string>
#include <vector>
@@ -58,6 +59,8 @@ class SanitizerArgs {
bool ImplicitCfiRuntime = false;
bool NeedsMemProfRt = false;
bool HwasanUseAliases = false;
+ llvm::AsanDetectStackUseAfterReturnMode AsanUseAfterReturn =
+ llvm::AsanDetectStackUseAfterReturnMode::Invalid;
public:
/// Parses the sanitizer arguments from an argument list.
diff --git a/clang/lib/Basic/Sanitizers.cpp b/clang/lib/Basic/Sanitizers.cpp
index 3a3b24a62e11..7d903c8fdf5e 100644
--- a/clang/lib/Basic/Sanitizers.cpp
+++ b/clang/lib/Basic/Sanitizers.cpp
@@ -88,4 +88,28 @@ llvm::AsanDtorKind AsanDtorKindFromString(StringRef kindStr) {
.Default(llvm::AsanDtorKind::Invalid);
}
+StringRef AsanDetectStackUseAfterReturnModeToString(
+ llvm::AsanDetectStackUseAfterReturnMode mode) {
+ switch (mode) {
+ case llvm::AsanDetectStackUseAfterReturnMode::Always:
+ return "always";
+ case llvm::AsanDetectStackUseAfterReturnMode::Runtime:
+ return "runtime";
+ case llvm::AsanDetectStackUseAfterReturnMode::Never:
+ return "never";
+ case llvm::AsanDetectStackUseAfterReturnMode::Invalid:
+ return "invalid";
+ }
+ return "invalid";
+}
+
+llvm::AsanDetectStackUseAfterReturnMode
+AsanDetectStackUseAfterReturnModeFromString(StringRef modeStr) {
+ return llvm::StringSwitch<llvm::AsanDetectStackUseAfterReturnMode>(modeStr)
+ .Case("always", llvm::AsanDetectStackUseAfterReturnMode::Always)
+ .Case("runtime", llvm::AsanDetectStackUseAfterReturnMode::Runtime)
+ .Case("never", llvm::AsanDetectStackUseAfterReturnMode::Never)
+ .Default(llvm::AsanDetectStackUseAfterReturnMode::Invalid);
+}
+
} // namespace clang
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index ad63ef63e5b1..bafcf7cb8a8f 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -65,6 +65,7 @@
#include "llvm/Transforms/InstCombine/InstCombine.h"
#include "llvm/Transforms/Instrumentation.h"
#include "llvm/Transforms/Instrumentation/AddressSanitizer.h"
+#include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h"
#include "llvm/Transforms/Instrumentation/BoundsChecking.h"
#include "llvm/Transforms/Instrumentation/DataFlowSanitizer.h"
#include "llvm/Transforms/Instrumentation/GCOVProfiler.h"
@@ -288,8 +289,10 @@ static void addAddressSanitizerPasses(const PassManagerBuilder &Builder,
bool UseOdrIndicator = CGOpts.SanitizeAddressUseOdrIndicator;
bool UseGlobalsGC = asanUseGlobalsGC(T, CGOpts);
llvm::AsanDtorKind DestructorKind = CGOpts.getSanitizeAddressDtor();
+ llvm::AsanDetectStackUseAfterReturnMode UseAfterReturn =
+ CGOpts.getSanitizeAddressUseAfterReturn();
PM.add(createAddressSanitizerFunctionPass(/*CompileKernel*/ false, Recover,
- UseAfterScope));
+ UseAfterScope, UseAfterReturn));
PM.add(createModuleAddressSanitizerLegacyPassPass(
/*CompileKernel*/ false, Recover, UseGlobalsGC, UseOdrIndicator,
DestructorKind));
@@ -298,7 +301,8 @@ static void addAddressSanitizerPasses(const PassManagerBuilder &Builder,
static void addKernelAddressSanitizerPasses(const PassManagerBuilder &Builder,
legacy::PassManagerBase &PM) {
PM.add(createAddressSanitizerFunctionPass(
- /*CompileKernel*/ true, /*Recover*/ true, /*UseAfterScope*/ false));
+ /*CompileKernel*/ true, /*Recover*/ true, /*UseAfterScope*/ false,
+ /*UseAfterReturn*/ llvm::AsanDetectStackUseAfterReturnMode::Never));
PM.add(createModuleAddressSanitizerLegacyPassPass(
/*CompileKernel*/ true, /*Recover*/ true, /*UseGlobalsGC*/ true,
/*UseOdrIndicator*/ false));
@@ -1144,12 +1148,14 @@ static void addSanitizers(const Triple &TargetTriple,
bool UseOdrIndicator = CodeGenOpts.SanitizeAddressUseOdrIndicator;
llvm::AsanDtorKind DestructorKind =
CodeGenOpts.getSanitizeAddressDtor();
+ llvm::AsanDetectStackUseAfterReturnMode UseAfterReturn =
+ CodeGenOpts.getSanitizeAddressUseAfterReturn();
MPM.addPass(RequireAnalysisPass<ASanGlobalsMetadataAnalysis, Module>());
MPM.addPass(ModuleAddressSanitizerPass(
CompileKernel, Recover, ModuleUseAfterScope, UseOdrIndicator,
DestructorKind));
- MPM.addPass(createModuleToFunctionPassAdaptor(
- AddressSanitizerPass(CompileKernel, Recover, UseAfterScope)));
+ MPM.addPass(createModuleToFunctionPassAdaptor(AddressSanitizerPass(
+ CompileKernel, Recover, UseAfterScope, UseAfterReturn)));
}
};
ASanPass(SanitizerKind::Address, false);
diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp
index 244d22b08ca0..68975aafcd37 100644
--- a/clang/lib/Driver/SanitizerArgs.cpp
+++ b/clang/lib/Driver/SanitizerArgs.cpp
@@ -18,6 +18,7 @@
#include "llvm/Support/SpecialCaseList.h"
#include "llvm/Support/TargetParser.h"
#include "llvm/Support/VirtualFileSystem.h"
+#include "llvm/Transforms/Instrumentation/AddressSanitizerOptions.h"
#include <memory>
using namespace clang;
@@ -841,6 +842,18 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
AsanDtorKind = parsedAsanDtorKind;
}
+ if (const auto *Arg = Args.getLastArg(
+ options::OPT_sanitize_address_use_after_return_EQ)) {
+ auto parsedAsanUseAfterReturn =
+ AsanDetectStackUseAfterReturnModeFromString(Arg->getValue());
+ if (parsedAsanUseAfterReturn ==
+ llvm::AsanDetectStackUseAfterReturnMode::Invalid) {
+ TC.getDriver().Diag(clang::diag::err_drv_unsupported_option_argument)
+ << Arg->getOption().getName() << Arg->getValue();
+ }
+ AsanUseAfterReturn = parsedAsanUseAfterReturn;
+ }
+
} else {
AsanUseAfterScope = false;
// -fsanitize=pointer-compare/pointer-subtract requires -fsanitize=address.
@@ -1112,6 +1125,12 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
AsanDtorKindToString(AsanDtorKind)));
}
+ if (AsanUseAfterReturn != llvm::AsanDetectStackUseAfterReturnMode::Invalid) {
+ CmdArgs.push_back(Args.MakeArgString(
+ "-fsanitize-address-use-after-return=" +
+ AsanDetectStackUseAfterReturnModeToString(AsanUseAfterReturn)));
+ }
+
if (!HwasanAbi.empty()) {
CmdArgs.push_back("-default-function-attr");
CmdArgs.push_back(Args.MakeArgString("hwasan-abi=" + HwasanAbi));
diff --git a/clang/test/CodeGen/asan-use-after-return.cpp b/clang/test/CodeGen/asan-use-after-return.cpp
new file mode 100644
index 000000000000..1b84f7b6ddf3
--- /dev/null
+++ b/clang/test/CodeGen/asan-use-after-return.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang_cc1 -fsanitize=address -emit-llvm -o - -triple x86_64-linux %s \
+// RUN: | FileCheck %s --check-prefixes=CHECK-RUNTIME \
+// RUN: --implicit-check-not="__asan_stack_malloc_always_"
+// RUN: %clang_cc1 -fsanitize=address -emit-llvm -o - -triple x86_64-linux %s \
+// RUN: -fsanitize-address-use-after-return=runtime \
+// RUN: | FileCheck %s --check-prefixes=CHECK-RUNTIME \
+// RUN: --implicit-check-not="__asan_stack_malloc_always_"
+// RUN: %clang_cc1 -fsanitize=address -emit-llvm -o - -triple x86_64-linux %s \
+// RUN: -fsanitize-address-use-after-return=always \
+// RUN: | FileCheck %s --check-prefixes=CHECK-ALWAYS \
+// RUN: --implicit-check-not=__asan_option_detect_stack_use_after_return \
+// RUN: --implicit-check-not="__asan_stack_malloc_{{[0-9]}}"
+// RUN: %clang_cc1 -fsanitize=address -emit-llvm -o - -triple x86_64-linux %s \
+// RUN: -fsanitize-address-use-after-return=never \
+// RUN: | FileCheck %s \
+// RUN: --implicit-check-not=__asan_option_detect_stack_use_after_return \
+// RUN: --implicit-check-not="__asan_stack_malloc_"
+
+// CHECK-RUNTIME: load{{.*}}@__asan_option_detect_stack_use_after_return
+// CHECK-RUNTIME: call{{.*}}__asan_stack_malloc_0
+// CHECK-ALWAYS: call{{.*}}__asan_stack_malloc_always_0
+
+int *function1() {
+ int x = 0;
+
+#pragma clang diagnostic ignored "-Wreturn-stack-address"
+ return &x;
+}
+
+int main() {
+ auto px = function1();
+ return 0;
+}
diff --git a/clang/test/Driver/cl-options.c b/clang/test/Driver/cl-options.c
index d1bd6f5146b4..258ac451fee0 100644
--- a/clang/test/Driver/cl-options.c
+++ b/clang/test/Driver/cl-options.c
@@ -452,7 +452,6 @@
// RUN: /FAs \
// RUN: /FAu \
// RUN: /favor:blend \
-// RUN: /fsanitize-address-use-after-return \
// RUN: /fno-sanitize-address-vcasan-lib \
// RUN: /Fifoo \
// RUN: /Fmfoo \
diff --git a/clang/test/Driver/fsanitize-use-after-return.c b/clang/test/Driver/fsanitize-use-after-return.c
new file mode 100644
index 000000000000..f262fa2ef0c7
--- /dev/null
+++ b/clang/test/Driver/fsanitize-use-after-return.c
@@ -0,0 +1,30 @@
+// Option should not be passed to the frontend by default.
+// RUN: %clang -target x86_64-apple-macosx10.15-gnu -fsanitize=address %s \
+// RUN: -### 2>&1 | \
+// RUN: FileCheck %s
+// CHECK-NOT: -fsanitize-address-use-after-return
+
+// RUN: %clang -target x86_64-apple-macosx10.15-gnu -fsanitize=address \
+// RUN: -fsanitize-address-use-after-return=never %s -### 2>&1 | \
+// RUN: FileCheck -check-prefix=CHECK-NEVER-ARG %s
+// CHECK-NEVER-ARG: "-fsanitize-address-use-after-return=never"
+
+// RUN: %clang -target x86_64-apple-macosx10.15-gnu -fsanitize=address \
+// RUN: -fsanitize-address-use-after-return=runtime %s -### 2>&1 | \
+// RUN: FileCheck -check-prefix=CHECK-RUNTIME %s
+// CHECK-RUNTIME: "-fsanitize-address-use-after-return=runtime"
+
+// RUN: %clang -target x86_64-apple-macosx10.15-gnu -fsanitize=address \
+// RUN: -fsanitize-address-use-after-return=always %s -### 2>&1 | \
+// RUN: FileCheck -check-prefix=CHECK-ALWAYS-ARG %s
+
+// RUN: %clang -target x86_64-apple-macosx10.15-gnu -fsanitize=address \
+// RUN: -fsanitize-address-use-after-return=never \
+// RUN: -fsanitize-address-use-after-return=always %s -### 2>&1 | \
+// RUN: FileCheck -check-prefix=CHECK-ALWAYS-ARG %s
+// CHECK-ALWAYS-ARG: "-fsanitize-address-use-after-return=always"
+
+// RUN: %clang -target x86_64-apple-macosx10.15-gnu -fsanitize=address \
+// RUN: -fsanitize-address-use-after-return=bad_arg %s -### 2>&1 | \
+// RUN: FileCheck -check-prefix=CHECK-INVALID-ARG %s
+// CHECK-INVALID-ARG: error: unsupported argument 'bad_arg' to option 'fsanitize-address-use-after-return='
diff --git a/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h b/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h
index 10b5d2d000b0..3781253d2694 100644
--- a/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h
+++ b/llvm/include/llvm/Transforms/Instrumentation/AddressSanitizer.h
@@ -99,9 +99,11 @@ class ASanGlobalsMetadataAnalysis
/// surrounding requested memory to be checked for invalid accesses.
class AddressSanitizerPass : public PassInfoMixin<AddressSanitizerPass> {
public:
- explicit AddressSanitizerPass(bool CompileKernel = false,
- bool Recover = false,
- bool UseAfterScope = false);
+ explicit AddressSanitizerPass(
+ bool CompileKernel = false, bool Recover = false,
+ bool UseAfterScope = false,
+ AsanDetectStackUseAfterReturnMode UseAfterReturn =
+ AsanDetectStackUseAfterReturnMode::Runtime);
PreservedAnalyses run(Function &F, FunctionAnalysisManager &AM);
static bool isRequired() { return true; }
@@ -109,6 +111,7 @@ class AddressSanitizerPass : public PassInfoMixin<AddressSanitizerPass> {
bool CompileKernel;
bool Recover;
bool UseAfterScope;
+ AsanDetectStackUseAfterReturnMode UseAfterReturn;
};
/// Public interface to the address sanitizer module pass for instrumenting code
@@ -135,9 +138,11 @@ class ModuleAddressSanitizerPass
};
// Insert AddressSanitizer (address sanity checking) instrumentation
-FunctionPass *createAddressSanitizerFunctionPass(bool CompileKernel = false,
- bool Recover = false,
- bool UseAfterScope = false);
+FunctionPass *createAddressSanitizerFunctionPass(
+ bool CompileKernel = false, bool Recover = false,
+ bool UseAfterScope = false,
+ AsanDetectStackUseAfterReturnMode UseAfterReturn =
+ AsanDetectStackUseAfterReturnMode::Runtime);
ModulePass *createModuleAddressSanitizerLegacyPassPass(
bool CompileKernel = false, bool Recover = false, bool UseGlobalsGC = true,
bool UseOdrIndicator = true,
diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
index c9f7693ef8da..dd26d3462eb7 100644
--- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
+++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp
@@ -633,17 +633,24 @@ char ASanGlobalsMetadataWrapperPass::ID = 0;
struct AddressSanitizer {
AddressSanitizer(Module &M, const GlobalsMetadata *GlobalsMD,
bool CompileKernel = false, bool Recover = false,
- bool UseAfterScope = false)
+ bool UseAfterScope = false,
+ AsanDetectStackUseAfterReturnMode UseAfterReturn =
+ AsanDetectStackUseAfterReturnMode::Runtime)
: CompileKernel(ClEnableKasan.getNumOccurrences() > 0 ? ClEnableKasan
: CompileKernel),
Recover(ClRecover.getNumOccurrences() > 0 ? ClRecover : Recover),
- UseAfterScope(UseAfterScope || ClUseAfterScope), GlobalsMD(*GlobalsMD) {
+ UseAfterScope(UseAfterScope || ClUseAfterScope),
+ UseAfterReturn(ClUseAfterReturn.getNumOccurrences() ? ClUseAfterReturn
+ : UseAfterReturn),
+ GlobalsMD(*GlobalsMD) {
C = &(M.getContext());
LongSize = M.getDataLayout().getPointerSizeInBits();
IntptrTy = Type::getIntNTy(*C, LongSize);
TargetTriple = Triple(M.getTargetTriple());
Mapping = getShadowMapping(TargetTriple, LongSize, this->CompileKernel);
+
+ assert(this->UseAfterReturn != AsanDetectStackUseAfterReturnMode::Invalid);
}
uint64_t getAllocaSizeInBytes(const AllocaInst &AI) const {
@@ -727,6 +734,7 @@ struct AddressSanitizer {
bool CompileKernel;
bool Recover;
bool UseAfterScope;
+ AsanDetectStackUseAfterReturnMode UseAfterReturn;
Type *IntptrTy;
ShadowMapping Mapping;
FunctionCallee AsanHandleNoReturnFunc;
@@ -754,11 +762,13 @@ class AddressSanitizerLegacyPass : public FunctionPass {
public:
static char ID;
- explicit AddressSanitizerLegacyPass(bool CompileKernel = false,
- bool Recover = false,
- bool UseAfterScope = false)
+ explicit AddressSanitizerLegacyPass(
+ bool CompileKernel = false, bool Recover = false,
+ bool UseAfterScope = false,
+ AsanDetectStackUseAfterReturnMode UseAfterReturn =
+ AsanDetectStackUseAfterReturnMode::Runtime)
: FunctionPass(ID), CompileKernel(CompileKernel), Recover(Recover),
- UseAfterScope(UseAfterScope) {
+ UseAfterScope(UseAfterScope), UseAfterReturn(UseAfterReturn) {
initializeAddressSanitizerLegacyPassPass(*PassRegistry::getPassRegistry());
}
@@ -777,7 +787,7 @@ class AddressSanitizerLegacyPass : public FunctionPass {
const TargetLibraryInfo *TLI =
&getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
AddressSanitizer ASan(*F.getParent(), &GlobalsMD, CompileKernel, Recover,
- UseAfterScope);
+ UseAfterScope, UseAfterReturn);
return ASan.instrumentFunction(F, TLI);
}
@@ -785,6 +795,7 @@ class AddressSanitizerLegacyPass : public FunctionPass {
bool CompileKernel;
bool Recover;
bool UseAfterScope;
+ AsanDetectStackUseAfterReturnMode UseAfterReturn;
};
class ModuleAddressSanitizer {
@@ -1227,10 +1238,11 @@ GlobalsMetadata ASanGlobalsMetadataAnalysis::run(Module &M,
return GlobalsMetadata(M);
}
-AddressSanitizerPass::AddressSanitizerPass(bool CompileKernel, bool Recover,
- bool UseAfterScope)
+AddressSanitizerPass::AddressSanitizerPass(
+ bool CompileKernel, bool Recover, bool UseAfterScope,
+ AsanDetectStackUseAfterReturnMode UseAfterReturn)
: CompileKernel(CompileKernel), Recover(Recover),
- UseAfterScope(UseAfterScope) {}
+ UseAfterScope(UseAfterScope), UseAfterReturn(UseAfterReturn) {}
PreservedAnalyses AddressSanitizerPass::run(Function &F,
AnalysisManager<Function> &AM) {
@@ -1238,7 +1250,8 @@ PreservedAnalyses AddressSanitizerPass::run(Function &F,
Module &M = *F.getParent();
if (auto *R = MAMProxy.getCachedResult<ASanGlobalsMetadataAnalysis>(M)) {
const TargetLibraryInfo *TLI = &AM.getResult<TargetLibraryAnalysis>(F);
- AddressSanitizer Sanitizer(M, R, CompileKernel, Recover, UseAfterScope);
+ AddressSanitizer Sanitizer(M, R, CompileKernel, Recover, UseAfterScope,
+ UseAfterReturn);
if (Sanitizer.instrumentFunction(F, TLI))
return PreservedAnalyses::none();
return PreservedAnalyses::all();
@@ -1285,11 +1298,12 @@ INITIALIZE_PASS_END(
"AddressSanitizer: detects use-after-free and out-of-bounds bugs.", false,
false)
-FunctionPass *llvm::createAddressSanitizerFunctionPass(bool CompileKernel,
- bool Recover,
- bool UseAfterScope) {
+FunctionPass *llvm::createAddressSanitizerFunctionPass(
+ bool CompileKernel, bool Recover, bool UseAfterScope,
+ AsanDetectStackUseAfterReturnMode UseAfterReturn) {
assert(!CompileKernel || Recover);
- return new AddressSanitizerLegacyPass(CompileKernel, Recover, UseAfterScope);
+ return new AddressSanitizerLegacyPass(CompileKernel, Recover, UseAfterScope,
+ UseAfterReturn);
}
char ModuleAddressSanitizerLegacyPass::ID = 0;
@@ -2953,33 +2967,20 @@ bool AddressSanitizer::LooksLikeCodeInBug11395(Instruction *I) {
void FunctionStackPoisoner::initializeCallbacks(Module &M) {
IRBuilder<> IRB(*C);
- switch (ClUseAfterReturn) {
- case AsanDetectStackUseAfterReturnMode::Always:
- for (int i = 0; i <= kMaxAsanStackMallocSizeClass; i++) {
- std::string Suffix = itostr(i);
- AsanStackMallocFunc[i] = M.getOrInsertFunction(
- kAsanStackMallocAlwaysNameTemplate + Suffix, IntptrTy, IntptrTy);
- AsanStackFreeFunc[i] =
- M.getOrInsertFunction(kAsanStackFreeNameTemplate + Suffix,
- IRB.getVoidTy(), IntptrTy, IntptrTy);
- }
- break;
- case AsanDetectStackUseAfterReturnMode::Runtime:
- for (int i = 0; i <= kMaxAsanStackMallocSizeClass; i++) {
- std::string Suffix = itostr(i);
- AsanStackMallocFunc[i] = M.getOrInsertFunction(
- kAsanStackMallocNameTemplate + Suffix, IntptrTy, IntptrTy);
- AsanStackFreeFunc[i] =
+ if (ASan.UseAfterReturn == AsanDetectStackUseAfterReturnMode::Always ||
+ ASan.UseAfterReturn == AsanDetectStackUseAfterReturnMode::Runtime) {
+ const char *MallocNameTemplate =
+ ASan.UseAfterReturn == AsanDetectStackUseAfterReturnMode::Always
+ ? kAsanStackMallocAlwaysNameTemplate
+ : kAsanStackMallocNameTemplate;
+ for (int Index = 0; Index <= kMaxAsanStackMallocSizeClass; Index++) {
+ std::string Suffix = itostr(Index);
+ AsanStackMallocFunc[Index] = M.getOrInsertFunction(
+ MallocNameTemplate + Suffix, IntptrTy, IntptrTy);
+ AsanStackFreeFunc[Index] =
M.getOrInsertFunction(kAsanStackFreeNameTemplate + Suffix,
IRB.getVoidTy(), IntptrTy, IntptrTy);
}
- break;
- case AsanDetectStackUseAfterReturnMode::Never:
- // Do Nothing
- break;
- case AsanDetectStackUseAfterReturnMode::Invalid:
- // Do Nothing
- break;
}
if (ASan.UseAfterScope) {
AsanPoisonStackMemoryFunc = M.getOrInsertFunction(
@@ -3331,7 +3332,7 @@ void FunctionStackPoisoner::processStaticAllocas() {
LLVM_DEBUG(dbgs() << DescriptionString << " --- " << L.FrameSize << "\n");
uint64_t LocalStackSize = L.FrameSize;
bool DoStackMalloc =
- ClUseAfterReturn != AsanDetectStackUseAfterReturnMode::Never &&
+ ASan.UseAfterReturn != AsanDetectStackUseAfterReturnMode::Never &&
!ASan.CompileKernel && LocalStackSize <= kMaxStackMallocSize;
bool DoDynamicAlloca = ClDynamicAllocaStack;
// Don't do dynamic alloca or stack malloc if:
@@ -3354,7 +3355,7 @@ void FunctionStackPoisoner::processStaticAllocas() {
if (DoStackMalloc) {
LocalStackBaseAlloca =
IRB.CreateAlloca(IntptrTy, nullptr, "asan_local_stack_base");
- if (ClUseAfterReturn == AsanDetectStackUseAfterReturnMode::Runtime) {
+ if (ASan.UseAfterReturn == AsanDetectStackUseAfterReturnMode::Runtime) {
// void *FakeStack = __asan_option_detect_stack_use_after_return
// ? __asan_stack_malloc_N(LocalStackSize)
// : nullptr;
@@ -3377,7 +3378,7 @@ void FunctionStackPoisoner::processStaticAllocas() {
FakeStack = createPHI(IRB, UseAfterReturnIsEnabled, FakeStackValue, Term,
ConstantInt::get(IntptrTy, 0));
} else {
- // assert(ClUseAfterReturn == AsanDetectStackUseAfterReturnMode:Always)
+ // assert(ASan.UseAfterReturn == AsanDetectStackUseAfterReturnMode:Always)
// void *FakeStack = __asan_stack_malloc_N(LocalStackSize);
// void *LocalStackBase = (FakeStack) ? FakeStack :
// alloca(LocalStackSize);
More information about the cfe-commits
mailing list