Cross-DSO control flow integrity (Clang part).
Clang-side cross-DSO CFI.
* Adds a command line flag -f[no-]sanitize-cfi-cross-dso.
* Links a runtime library when enabled.
* Emits __cfi_slowpath calls is bitset test fails.
* Emits extra hash-based bitsets for external CFI checks.
* Sets a module flag to enable __cfi_check generation during LTO.
This mode does not yet support diagnostics.
llvm-svn: 255694
diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp
index efee065..82ac2b0 100644
--- a/clang/lib/Driver/SanitizerArgs.cpp
+++ b/clang/lib/Driver/SanitizerArgs.cpp
@@ -160,7 +160,12 @@
return (Sanitizers.Mask & NeedsUbsanRt & ~TrapSanitizers.Mask) &&
!Sanitizers.has(Address) &&
!Sanitizers.has(Memory) &&
- !Sanitizers.has(Thread);
+ !Sanitizers.has(Thread) &&
+ !CfiCrossDso;
+}
+
+bool SanitizerArgs::needsCfiRt() const {
+ return CfiCrossDso;
}
bool SanitizerArgs::requiresPIE() const {
@@ -184,6 +189,7 @@
AsanFieldPadding = 0;
AsanSharedRuntime = false;
LinkCXXRuntimes = false;
+ CfiCrossDso = false;
}
SanitizerArgs::SanitizerArgs(const ToolChain &TC,
@@ -430,6 +436,14 @@
TC.getTriple().getArch() == llvm::Triple::x86_64);
}
+ if (AllAddedKinds & CFI) {
+ CfiCrossDso = Args.hasFlag(options::OPT_fsanitize_cfi_cross_dso,
+ options::OPT_fno_sanitize_cfi_cross_dso, false);
+ // Without PIE, external function address may resolve to a PLT record, which
+ // can not be verified by the target module.
+ NeedPIE |= CfiCrossDso;
+ }
+
// Parse -f(no-)?sanitize-coverage flags if coverage is supported by the
// enabled sanitizers.
if (AllAddedKinds & SupportsCoverage) {
@@ -580,6 +594,9 @@
if (MsanUseAfterDtor)
CmdArgs.push_back(Args.MakeArgString("-fsanitize-memory-use-after-dtor"));
+ if (CfiCrossDso)
+ CmdArgs.push_back(Args.MakeArgString("-fsanitize-cfi-cross-dso"));
+
if (AsanFieldPadding)
CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-field-padding=" +
llvm::utostr(AsanFieldPadding)));