forked from OSchip/llvm-project
[Driver] Add Scudo as a possible -fsanitize= option
Summary: This change adds Scudo as a possible Sanitizer option via -fsanitize=. This allows for easier static & shared linking of the Scudo library, it allows us to enforce PIE (otherwise the security of the allocator is moot), and check for incompatible Sanitizers combo. In its current form, Scudo is not compatible with any other Sanitizer, but the plan is to make it work in conjunction with UBsan (-fsanitize=scudo,undefined), which will require additional work outside of the scope of this change. Reviewers: eugenis, kcc, alekseyshl Reviewed By: eugenis, alekseyshl Subscribers: llvm-commits, srhines Differential Revision: https://reviews.llvm.org/D39334 llvm-svn: 317337
This commit is contained in:
parent
594d217502
commit
8acdc98271
|
@ -135,6 +135,9 @@ SANITIZER("efficiency-working-set", EfficiencyWorkingSet)
|
|||
SANITIZER_GROUP("efficiency-all", Efficiency,
|
||||
EfficiencyCacheFrag | EfficiencyWorkingSet)
|
||||
|
||||
// Scudo hardened allocator
|
||||
SANITIZER("scudo", Scudo)
|
||||
|
||||
// Magic group, containing all sanitizers. For example, "-fno-sanitize=all"
|
||||
// can be used to disable all the sanitizers.
|
||||
SANITIZER_GROUP("all", All, ~0ULL)
|
||||
|
|
|
@ -72,6 +72,7 @@ class SanitizerArgs {
|
|||
bool needsEsanRt() const {
|
||||
return Sanitizers.hasOneOf(SanitizerKind::Efficiency);
|
||||
}
|
||||
bool needsScudoRt() const { return Sanitizers.has(SanitizerKind::Scudo); }
|
||||
|
||||
bool requiresPIE() const;
|
||||
bool needsUnwindTables() const;
|
||||
|
|
|
@ -30,7 +30,7 @@ enum : SanitizerMask {
|
|||
NeedsUbsanCxxRt = Vptr | CFI,
|
||||
NotAllowedWithTrap = Vptr,
|
||||
NotAllowedWithMinimalRuntime = Vptr,
|
||||
RequiresPIE = DataFlow,
|
||||
RequiresPIE = DataFlow | Scudo,
|
||||
NeedsUnwindTables = Address | Thread | Memory | DataFlow,
|
||||
SupportsCoverage = Address | KernelAddress | Memory | Leak | Undefined |
|
||||
Integer | Nullability | DataFlow | Fuzzer | FuzzerNoLink,
|
||||
|
@ -173,7 +173,7 @@ static SanitizerMask parseSanitizeTrapArgs(const Driver &D,
|
|||
bool SanitizerArgs::needsUbsanRt() const {
|
||||
// All of these include ubsan.
|
||||
if (needsAsanRt() || needsMsanRt() || needsTsanRt() || needsDfsanRt() ||
|
||||
needsLsanRt() || needsCfiDiagRt())
|
||||
needsLsanRt() || needsCfiDiagRt() || needsScudoRt())
|
||||
return false;
|
||||
|
||||
return (Sanitizers.Mask & NeedsUbsanRt & ~TrapSanitizers.Mask) ||
|
||||
|
@ -370,17 +370,14 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
|
|||
|
||||
// Warn about incompatible groups of sanitizers.
|
||||
std::pair<SanitizerMask, SanitizerMask> IncompatibleGroups[] = {
|
||||
std::make_pair(Address, Thread), std::make_pair(Address, Memory),
|
||||
std::make_pair(Thread, Memory), std::make_pair(Leak, Thread),
|
||||
std::make_pair(Leak, Memory), std::make_pair(KernelAddress, Address),
|
||||
std::make_pair(KernelAddress, Leak),
|
||||
std::make_pair(KernelAddress, Thread),
|
||||
std::make_pair(KernelAddress, Memory),
|
||||
std::make_pair(Efficiency, Address),
|
||||
std::make_pair(Efficiency, Leak),
|
||||
std::make_pair(Efficiency, Thread),
|
||||
std::make_pair(Efficiency, Memory),
|
||||
std::make_pair(Efficiency, KernelAddress)};
|
||||
std::make_pair(Address, Thread | Memory),
|
||||
std::make_pair(Thread, Memory),
|
||||
std::make_pair(Leak, Thread | Memory),
|
||||
std::make_pair(KernelAddress, Address| Leak | Thread | Memory),
|
||||
std::make_pair(Efficiency, Address | Leak | Thread | Memory |
|
||||
KernelAddress),
|
||||
std::make_pair(Scudo, Address | Leak | Thread | Memory | KernelAddress |
|
||||
Efficiency) };
|
||||
for (auto G : IncompatibleGroups) {
|
||||
SanitizerMask Group = G.first;
|
||||
if (Kinds & Group) {
|
||||
|
|
|
@ -566,7 +566,6 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
|
|||
if (!Args.hasArg(options::OPT_shared) && !TC.getTriple().isAndroid())
|
||||
HelperStaticRuntimes.push_back("asan-preinit");
|
||||
}
|
||||
|
||||
if (SanArgs.needsUbsanRt()) {
|
||||
if (SanArgs.requiresMinimalRuntime()) {
|
||||
SharedRuntimes.push_back("ubsan_minimal");
|
||||
|
@ -574,6 +573,8 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
|
|||
SharedRuntimes.push_back("ubsan_standalone");
|
||||
}
|
||||
}
|
||||
if (SanArgs.needsScudoRt())
|
||||
SharedRuntimes.push_back("scudo");
|
||||
}
|
||||
|
||||
// The stats_client library is also statically linked into DSOs.
|
||||
|
@ -630,6 +631,11 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
|
|||
}
|
||||
if (SanArgs.needsEsanRt())
|
||||
StaticRuntimes.push_back("esan");
|
||||
if (SanArgs.needsScudoRt()) {
|
||||
StaticRuntimes.push_back("scudo");
|
||||
if (SanArgs.linkCXXRuntimes())
|
||||
StaticRuntimes.push_back("scudo_cxx");
|
||||
}
|
||||
}
|
||||
|
||||
// Should be called before we add system libraries (C++ ABI, libstdc++/libc++,
|
||||
|
|
|
@ -845,9 +845,10 @@ SanitizerMask Linux::getSupportedSanitizers() const {
|
|||
Res |= SanitizerKind::Memory;
|
||||
if (IsX86_64 || IsMIPS64)
|
||||
Res |= SanitizerKind::Efficiency;
|
||||
if (IsX86 || IsX86_64) {
|
||||
if (IsX86 || IsX86_64)
|
||||
Res |= SanitizerKind::Function;
|
||||
}
|
||||
if (IsX86_64 || IsMIPS64 || IsAArch64 || IsX86 || IsArmArch)
|
||||
Res |= SanitizerKind::Scudo;
|
||||
return Res;
|
||||
}
|
||||
|
||||
|
|
|
@ -1138,6 +1138,7 @@ static bool HasFeature(const Preprocessor &PP, StringRef Feature) {
|
|||
.Case("dataflow_sanitizer", LangOpts.Sanitize.has(SanitizerKind::DataFlow))
|
||||
.Case("efficiency_sanitizer",
|
||||
LangOpts.Sanitize.hasOneOf(SanitizerKind::Efficiency))
|
||||
.Case("scudo", LangOpts.Sanitize.hasOneOf(SanitizerKind::Scudo))
|
||||
// Objective-C features
|
||||
.Case("objc_arr", LangOpts.ObjCAutoRefCount) // FIXME: REMOVE?
|
||||
.Case("objc_arc", LangOpts.ObjCAutoRefCount)
|
||||
|
|
|
@ -608,3 +608,29 @@
|
|||
// CHECK-CFI-NOICALL-MINIMAL: "-fsanitize=cfi-derived-cast,cfi-unrelated-cast,cfi-nvcall,cfi-vcall"
|
||||
// CHECK-CFI-NOICALL-MINIMAL: "-fsanitize-trap=cfi-derived-cast,cfi-unrelated-cast,cfi-nvcall,cfi-vcall"
|
||||
// CHECK-CFI-NOICALL-MINIMAL: "-fsanitize-minimal-runtime"
|
||||
|
||||
// RUN: %clang -target aarch64-linux-gnu -fsanitize=scudo %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO
|
||||
// RUN: %clang -target arm-linux-androideabi -fsanitize=scudo %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO
|
||||
// RUN: %clang -target x86_64-linux-gnu -fsanitize=scudo %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO
|
||||
// RUN: %clang -target i386-linux-gnu -fsanitize=scudo %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO
|
||||
// CHECK-SCUDO: "-fsanitize=scudo"
|
||||
|
||||
// RUN: %clang -target x86_64-linux-gnu -fsanitize=scudo %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO-PIE
|
||||
// RUN: %clang -target arm-linux-androideabi -fsanitize=scudo %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO-PIE
|
||||
// CHECK-SCUDO-PIE: "-mrelocation-model" "pic" "-pic-level" "2" "-pic-is-pie"
|
||||
// CHECK-SCUDO-PIE: "-pie"
|
||||
|
||||
// RUN: %clang -target x86_64-linux-gnu -fsanitize=scudo,undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO-UBSAN
|
||||
// CHECK-SCUDO-UBSAN: "-fsanitize={{.*}}scudo"
|
||||
|
||||
// RUN: %clang -target powerpc-unknown-linux -fsanitize=scudo %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-SCUDO
|
||||
// CHECK-NO-SCUDO: unsupported option
|
||||
|
||||
// RUN: %clang -target x86_64-linux-gnu -fsanitize=scudo,address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO-ASAN
|
||||
// CHECK-SCUDO-ASAN: error: invalid argument '-fsanitize=scudo' not allowed with '-fsanitize=address'
|
||||
// RUN: %clang -target x86_64-linux-gnu -fsanitize=scudo,leak %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO-LSAN
|
||||
// CHECK-SCUDO-LSAN: error: invalid argument '-fsanitize=scudo' not allowed with '-fsanitize=leak'
|
||||
// RUN: %clang -target x86_64-linux-gnu -fsanitize=scudo,memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO-MSAN
|
||||
// CHECK-SCUDO-MSAN: error: invalid argument '-fsanitize=scudo' not allowed with '-fsanitize=memory'
|
||||
// RUN: %clang -target x86_64-linux-gnu -fsanitize=scudo,thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO-TSAN
|
||||
// CHECK-SCUDO-TSAN: error: invalid argument '-fsanitize=scudo' not allowed with '-fsanitize=thread'
|
||||
|
|
|
@ -644,3 +644,53 @@
|
|||
//
|
||||
// CHECK-ESAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
|
||||
// CHECK-ESAN-LINUX: libclang_rt.esan-x86_64.a
|
||||
|
||||
// RUN: %clang -fsanitize=scudo %s -### -o %t.o 2>&1 \
|
||||
// RUN: -target i386-unknown-linux -fuse-ld=ld \
|
||||
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
|
||||
// RUN: | FileCheck --check-prefix=CHECK-SCUDO-LINUX %s
|
||||
// CHECK-SCUDO-LINUX: "{{.*}}ld{{(.exe)?}}"
|
||||
// CHECK-SCUDO-LINUX: "-pie"
|
||||
// CHECK-SCUDO-LINUX: "-whole-archive" "{{.*}}libclang_rt.scudo-i386.a" "-no-whole-archive"
|
||||
// CHECK-SCUDO-LINUX-NOT: "-lstdc++"
|
||||
// CHECK-SCUDO-LINUX: "-lpthread"
|
||||
// CHECK-SCUDO-LINUX: "-ldl"
|
||||
|
||||
// RUN: %clang -no-canonical-prefixes %s -### -o %t.so -shared 2>&1 \
|
||||
// RUN: -target i386-unknown-linux -fuse-ld=ld -fsanitize=scudo -shared-libsan \
|
||||
// RUN: -resource-dir=%S/Inputs/resource_dir \
|
||||
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
|
||||
// RUN: | FileCheck --check-prefix=CHECK-SCUDO-SHARED-LINUX %s
|
||||
//
|
||||
// CHECK-SCUDO-SHARED-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
|
||||
// CHECK-SCUDO-SHARED-LINUX-NOT: "-lc"
|
||||
// CHECK-SCUDO-SHARED-LINUX-NOT: libclang_rt.scudo-i386.a"
|
||||
// CHECK-SCUDO-SHARED-LINUX: libclang_rt.scudo-i386.so"
|
||||
// CHECK-SCUDO-SHARED-LINUX-NOT: "-lpthread"
|
||||
// CHECK-SCUDO-SHARED-LINUX-NOT: "-lrt"
|
||||
// CHECK-SCUDO-SHARED-LINUX-NOT: "-ldl"
|
||||
// CHECK-SCUDO-SHARED-LINUX-NOT: "-export-dynamic"
|
||||
// CHECK-SCUDO-SHARED-LINUX-NOT: "--dynamic-list"
|
||||
|
||||
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
|
||||
// RUN: -target arm-linux-androideabi -fuse-ld=ld -fsanitize=scudo \
|
||||
// RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \
|
||||
// RUN: | FileCheck --check-prefix=CHECK-SCUDO-ANDROID %s
|
||||
//
|
||||
// CHECK-SCUDO-ANDROID: "{{(.*[^.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
|
||||
// CHECK-SCUDO-ANDROID-NOT: "-lc"
|
||||
// CHECK-SCUDO-ANDROID: "-pie"
|
||||
// CHECK-SCUDO-ANDROID-NOT: "-lpthread"
|
||||
// CHECK-SCUDO-ANDROID: libclang_rt.scudo-arm-android.so"
|
||||
// CHECK-SCUDO-ANDROID-NOT: "-lpthread"
|
||||
|
||||
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
|
||||
// RUN: -target arm-linux-androideabi -fuse-ld=ld -fsanitize=scudo \
|
||||
// RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \
|
||||
// RUN: -static-libsan \
|
||||
// RUN: | FileCheck --check-prefix=CHECK-SCUDO-ANDROID-STATIC %s
|
||||
// CHECK-SCUDO-ANDROID-STATIC: "{{(.*[^.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
|
||||
// CHECK-SCUDO-ANDROID-STATIC: "-pie"
|
||||
// CHECK-SCUDO-ANDROID-STATIC: "-whole-archive" "{{.*}}libclang_rt.scudo-arm-android.a" "-no-whole-archive"
|
||||
// CHECK-SCUDO-ANDROID-STATIC-NOT: "-lstdc++"
|
||||
// CHECK-SCUDO-ANDROID-STATIC: "-lpthread"
|
||||
|
|
Loading…
Reference in New Issue