Author: cryptoad Date: Fri Nov 3 10:04:13 2017 New Revision: 317337 URL: http://llvm.org/viewvc/llvm-project?rev=317337&view=rev Log: [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 Modified: cfe/trunk/include/clang/Basic/Sanitizers.def cfe/trunk/include/clang/Driver/SanitizerArgs.h cfe/trunk/lib/Driver/SanitizerArgs.cpp cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp cfe/trunk/lib/Driver/ToolChains/Linux.cpp cfe/trunk/lib/Lex/PPMacroExpansion.cpp cfe/trunk/test/Driver/fsanitize.c cfe/trunk/test/Driver/sanitizer-ld.c Modified: cfe/trunk/include/clang/Basic/Sanitizers.def URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/Sanitizers.def?rev=317337&r1=317336&r2=317337&view=diff ============================================================================== --- cfe/trunk/include/clang/Basic/Sanitizers.def (original) +++ cfe/trunk/include/clang/Basic/Sanitizers.def Fri Nov 3 10:04:13 2017 @@ -135,6 +135,9 @@ SANITIZER("efficiency-working-set", Effi 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) Modified: cfe/trunk/include/clang/Driver/SanitizerArgs.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/SanitizerArgs.h?rev=317337&r1=317336&r2=317337&view=diff ============================================================================== --- cfe/trunk/include/clang/Driver/SanitizerArgs.h (original) +++ cfe/trunk/include/clang/Driver/SanitizerArgs.h Fri Nov 3 10:04:13 2017 @@ -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; Modified: cfe/trunk/lib/Driver/SanitizerArgs.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/SanitizerArgs.cpp?rev=317337&r1=317336&r2=317337&view=diff ============================================================================== --- cfe/trunk/lib/Driver/SanitizerArgs.cpp (original) +++ cfe/trunk/lib/Driver/SanitizerArgs.cpp Fri Nov 3 10:04:13 2017 @@ -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 parseSanitizeTrapAr 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 ToolC // 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) { Modified: cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp?rev=317337&r1=317336&r2=317337&view=diff ============================================================================== --- cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp (original) +++ cfe/trunk/lib/Driver/ToolChains/CommonArgs.cpp Fri Nov 3 10:04:13 2017 @@ -566,7 +566,6 @@ collectSanitizerRuntimes(const ToolChain 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 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 } 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++, Modified: cfe/trunk/lib/Driver/ToolChains/Linux.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/ToolChains/Linux.cpp?rev=317337&r1=317336&r2=317337&view=diff ============================================================================== --- cfe/trunk/lib/Driver/ToolChains/Linux.cpp (original) +++ cfe/trunk/lib/Driver/ToolChains/Linux.cpp Fri Nov 3 10:04:13 2017 @@ -845,9 +845,10 @@ SanitizerMask Linux::getSupportedSanitiz 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; } Modified: cfe/trunk/lib/Lex/PPMacroExpansion.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Lex/PPMacroExpansion.cpp?rev=317337&r1=317336&r2=317337&view=diff ============================================================================== --- cfe/trunk/lib/Lex/PPMacroExpansion.cpp (original) +++ cfe/trunk/lib/Lex/PPMacroExpansion.cpp Fri Nov 3 10:04:13 2017 @@ -1138,6 +1138,7 @@ static bool HasFeature(const Preprocesso .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) Modified: cfe/trunk/test/Driver/fsanitize.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/fsanitize.c?rev=317337&r1=317336&r2=317337&view=diff ============================================================================== --- cfe/trunk/test/Driver/fsanitize.c (original) +++ cfe/trunk/test/Driver/fsanitize.c Fri Nov 3 10:04:13 2017 @@ -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' Modified: cfe/trunk/test/Driver/sanitizer-ld.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/sanitizer-ld.c?rev=317337&r1=317336&r2=317337&view=diff ============================================================================== --- cfe/trunk/test/Driver/sanitizer-ld.c (original) +++ cfe/trunk/test/Driver/sanitizer-ld.c Fri Nov 3 10:04:13 2017 @@ -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" _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits