summaryrefslogtreecommitdiffstats
path: root/clang
diff options
context:
space:
mode:
authorKostya Kortchinsky <kostyak@google.com>2017-11-03 17:04:13 +0000
committerKostya Kortchinsky <kostyak@google.com>2017-11-03 17:04:13 +0000
commit8acdc98271c9efa2303e371b4ebc4b7410a30d9f (patch)
tree97c283d45001a83effce7c0b920af3ead8498840 /clang
parent594d217502caef3976eab52b759b469fa52551a4 (diff)
downloadbcm5719-llvm-8acdc98271c9efa2303e371b4ebc4b7410a30d9f.tar.gz
bcm5719-llvm-8acdc98271c9efa2303e371b4ebc4b7410a30d9f.zip
[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
Diffstat (limited to 'clang')
-rw-r--r--clang/include/clang/Basic/Sanitizers.def3
-rw-r--r--clang/include/clang/Driver/SanitizerArgs.h1
-rw-r--r--clang/lib/Driver/SanitizerArgs.cpp23
-rw-r--r--clang/lib/Driver/ToolChains/CommonArgs.cpp8
-rw-r--r--clang/lib/Driver/ToolChains/Linux.cpp5
-rw-r--r--clang/lib/Lex/PPMacroExpansion.cpp1
-rw-r--r--clang/test/Driver/fsanitize.c26
-rw-r--r--clang/test/Driver/sanitizer-ld.c50
8 files changed, 101 insertions, 16 deletions
diff --git a/clang/include/clang/Basic/Sanitizers.def b/clang/include/clang/Basic/Sanitizers.def
index d6df6171729..3586fc228d0 100644
--- a/clang/include/clang/Basic/Sanitizers.def
+++ b/clang/include/clang/Basic/Sanitizers.def
@@ -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)
diff --git a/clang/include/clang/Driver/SanitizerArgs.h b/clang/include/clang/Driver/SanitizerArgs.h
index 19309c3f3b7..44083aec16f 100644
--- a/clang/include/clang/Driver/SanitizerArgs.h
+++ b/clang/include/clang/Driver/SanitizerArgs.h
@@ -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;
diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp
index 32c1c43a5bd..8d9f32f8483 100644
--- a/clang/lib/Driver/SanitizerArgs.cpp
+++ b/clang/lib/Driver/SanitizerArgs.cpp
@@ -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) {
diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp
index b359cbb77ef..91f653a53e8 100644
--- a/clang/lib/Driver/ToolChains/CommonArgs.cpp
+++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp
@@ -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++,
diff --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp
index 613a9f3c88e..9b722166c5f 100644
--- a/clang/lib/Driver/ToolChains/Linux.cpp
+++ b/clang/lib/Driver/ToolChains/Linux.cpp
@@ -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;
}
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index b0330f28813..9f0c88dd976 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -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)
diff --git a/clang/test/Driver/fsanitize.c b/clang/test/Driver/fsanitize.c
index dcca96ff3a8..3de6fa0b35a 100644
--- a/clang/test/Driver/fsanitize.c
+++ b/clang/test/Driver/fsanitize.c
@@ -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'
diff --git a/clang/test/Driver/sanitizer-ld.c b/clang/test/Driver/sanitizer-ld.c
index f03714c4b57..8fc31fe37a6 100644
--- a/clang/test/Driver/sanitizer-ld.c
+++ b/clang/test/Driver/sanitizer-ld.c
@@ -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"
OpenPOWER on IntegriCloud