diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/Decl.cpp | 12 | ||||
-rw-r--r-- | clang/lib/Basic/CMakeLists.txt | 1 | ||||
-rw-r--r-- | clang/lib/Basic/SanitizerBlacklist.cpp | 27 | ||||
-rw-r--r-- | clang/lib/Basic/SanitizerSpecialCaseList.cpp | 64 | ||||
-rw-r--r-- | clang/lib/Basic/XRayLists.cpp | 14 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGClass.cpp | 37 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGDeclCXX.cpp | 30 | ||||
-rw-r--r-- | clang/lib/CodeGen/CGExpr.cpp | 2 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenFunction.cpp | 15 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.cpp | 20 | ||||
-rw-r--r-- | clang/lib/CodeGen/CodeGenModule.h | 3 |
11 files changed, 156 insertions, 69 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index f77345f9c2d..df30426ebb6 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -3923,9 +3923,9 @@ void RecordDecl::LoadFieldsFromExternalStorage() const { bool RecordDecl::mayInsertExtraPadding(bool EmitRemark) const { ASTContext &Context = getASTContext(); - if (!Context.getLangOpts().Sanitize.hasOneOf( - SanitizerKind::Address | SanitizerKind::KernelAddress) || - !Context.getLangOpts().SanitizeAddressFieldPadding) + const SanitizerMask EnabledAsanMask = Context.getLangOpts().Sanitize.Mask & + (SanitizerKind::Address | SanitizerKind::KernelAddress); + if (!EnabledAsanMask || !Context.getLangOpts().SanitizeAddressFieldPadding) return false; const auto &Blacklist = Context.getSanitizerBlacklist(); const auto *CXXRD = dyn_cast<CXXRecordDecl>(this); @@ -3943,9 +3943,11 @@ bool RecordDecl::mayInsertExtraPadding(bool EmitRemark) const { ReasonToReject = 4; // has trivial destructor. else if (CXXRD->isStandardLayout()) ReasonToReject = 5; // is standard layout. - else if (Blacklist.isBlacklistedLocation(getLocation(), "field-padding")) + else if (Blacklist.isBlacklistedLocation(EnabledAsanMask, getLocation(), + "field-padding")) ReasonToReject = 6; // is in a blacklisted file. - else if (Blacklist.isBlacklistedType(getQualifiedNameAsString(), + else if (Blacklist.isBlacklistedType(EnabledAsanMask, + getQualifiedNameAsString(), "field-padding")) ReasonToReject = 7; // is blacklisted. diff --git a/clang/lib/Basic/CMakeLists.txt b/clang/lib/Basic/CMakeLists.txt index 2bec0e83ae9..d0c9b902f67 100644 --- a/clang/lib/Basic/CMakeLists.txt +++ b/clang/lib/Basic/CMakeLists.txt @@ -62,6 +62,7 @@ add_clang_library(clangBasic OpenMPKinds.cpp OperatorPrecedence.cpp SanitizerBlacklist.cpp + SanitizerSpecialCaseList.cpp Sanitizers.cpp SourceLocation.cpp SourceManager.cpp diff --git a/clang/lib/Basic/SanitizerBlacklist.cpp b/clang/lib/Basic/SanitizerBlacklist.cpp index de78c94bc19..199ded1f317 100644 --- a/clang/lib/Basic/SanitizerBlacklist.cpp +++ b/clang/lib/Basic/SanitizerBlacklist.cpp @@ -17,30 +17,35 @@ using namespace clang; SanitizerBlacklist::SanitizerBlacklist( const std::vector<std::string> &BlacklistPaths, SourceManager &SM) - : SCL(llvm::SpecialCaseList::createOrDie(BlacklistPaths)), SM(SM) {} + : SSCL(SanitizerSpecialCaseList::createOrDie(BlacklistPaths)), SM(SM) {} -bool SanitizerBlacklist::isBlacklistedGlobal(StringRef GlobalName, +bool SanitizerBlacklist::isBlacklistedGlobal(SanitizerMask Mask, + StringRef GlobalName, StringRef Category) const { - return SCL->inSection("global", GlobalName, Category); + return SSCL->inSection(Mask, "global", GlobalName, Category); } -bool SanitizerBlacklist::isBlacklistedType(StringRef MangledTypeName, +bool SanitizerBlacklist::isBlacklistedType(SanitizerMask Mask, + StringRef MangledTypeName, StringRef Category) const { - return SCL->inSection("type", MangledTypeName, Category); + return SSCL->inSection(Mask, "type", MangledTypeName, Category); } -bool SanitizerBlacklist::isBlacklistedFunction(StringRef FunctionName) const { - return SCL->inSection("fun", FunctionName); +bool SanitizerBlacklist::isBlacklistedFunction(SanitizerMask Mask, + StringRef FunctionName) const { + return SSCL->inSection(Mask, "fun", FunctionName); } -bool SanitizerBlacklist::isBlacklistedFile(StringRef FileName, +bool SanitizerBlacklist::isBlacklistedFile(SanitizerMask Mask, + StringRef FileName, StringRef Category) const { - return SCL->inSection("src", FileName, Category); + return SSCL->inSection(Mask, "src", FileName, Category); } -bool SanitizerBlacklist::isBlacklistedLocation(SourceLocation Loc, +bool SanitizerBlacklist::isBlacklistedLocation(SanitizerMask Mask, + SourceLocation Loc, StringRef Category) const { return Loc.isValid() && - isBlacklistedFile(SM.getFilename(SM.getFileLoc(Loc)), Category); + isBlacklistedFile(Mask, SM.getFilename(SM.getFileLoc(Loc)), Category); } diff --git a/clang/lib/Basic/SanitizerSpecialCaseList.cpp b/clang/lib/Basic/SanitizerSpecialCaseList.cpp new file mode 100644 index 00000000000..4dd52ee8704 --- /dev/null +++ b/clang/lib/Basic/SanitizerSpecialCaseList.cpp @@ -0,0 +1,64 @@ +//===--- SanitizerSpecialCaseList.cpp - SCL for sanitizers ----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// An extension of SpecialCaseList to allowing querying sections by +// SanitizerMask. +// +//===----------------------------------------------------------------------===// +#include "clang/Basic/SanitizerSpecialCaseList.h" + +using namespace clang; + +std::unique_ptr<SanitizerSpecialCaseList> +SanitizerSpecialCaseList::create(const std::vector<std::string> &Paths, + std::string &Error) { + std::unique_ptr<clang::SanitizerSpecialCaseList> SSCL( + new SanitizerSpecialCaseList()); + if (SSCL->createInternal(Paths, Error)) { + SSCL->createSanitizerSections(); + return SSCL; + } + return nullptr; +} + +std::unique_ptr<SanitizerSpecialCaseList> +SanitizerSpecialCaseList::createOrDie(const std::vector<std::string> &Paths) { + std::string Error; + if (auto SSCL = create(Paths, Error)) + return SSCL; + llvm::report_fatal_error(Error); +} + +void SanitizerSpecialCaseList::createSanitizerSections() { + for (auto &S : Sections) { + SanitizerMask Mask = 0; + +#define SANITIZER(NAME, ID) \ + if (S.SectionMatcher->match(NAME)) \ + Mask |= SanitizerKind::ID; +#define SANITIZER_GROUP(NAME, ID, ALIAS) SANITIZER(NAME, ID) + +#include "clang/Basic/Sanitizers.def" +#undef SANITIZER +#undef SANITIZER_GROUP + + SanitizerSections.emplace_back(Mask, S.Entries); + } +} + +bool SanitizerSpecialCaseList::inSection(SanitizerMask Mask, StringRef Prefix, + StringRef Query, + StringRef Category) const { + for (auto &S : SanitizerSections) + if ((S.Mask & Mask) && + SpecialCaseList::inSection(S.Entries, Prefix, Query, Category)) + return true; + + return false; +} diff --git a/clang/lib/Basic/XRayLists.cpp b/clang/lib/Basic/XRayLists.cpp index 0a439c7af90..462777d5340 100644 --- a/clang/lib/Basic/XRayLists.cpp +++ b/clang/lib/Basic/XRayLists.cpp @@ -26,11 +26,13 @@ XRayFunctionFilter::ImbueAttribute XRayFunctionFilter::shouldImbueFunction(StringRef FunctionName) const { // First apply the always instrument list, than if it isn't an "always" see // whether it's treated as a "never" instrument function. - if (AlwaysInstrument->inSection("fun", FunctionName, "arg1")) + if (AlwaysInstrument->inSection("xray_always_instrument", "fun", FunctionName, + "arg1")) return ImbueAttribute::ALWAYS_ARG1; - if (AlwaysInstrument->inSection("fun", FunctionName)) + if (AlwaysInstrument->inSection("xray_always_instrument", "fun", + FunctionName)) return ImbueAttribute::ALWAYS; - if (NeverInstrument->inSection("fun", FunctionName)) + if (NeverInstrument->inSection("xray_never_instrument", "fun", FunctionName)) return ImbueAttribute::NEVER; return ImbueAttribute::NONE; } @@ -38,9 +40,11 @@ XRayFunctionFilter::shouldImbueFunction(StringRef FunctionName) const { XRayFunctionFilter::ImbueAttribute XRayFunctionFilter::shouldImbueFunctionsInFile(StringRef Filename, StringRef Category) const { - if (AlwaysInstrument->inSection("src", Filename, Category)) + if (AlwaysInstrument->inSection("xray_always_instrument", "src", Filename, + Category)) return ImbueAttribute::ALWAYS; - if (NeverInstrument->inSection("src", Filename, Category)) + if (NeverInstrument->inSection("xray_never_instrument", "src", Filename, + Category)) return ImbueAttribute::NEVER; return ImbueAttribute::NONE; } diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp index 1ebe5219cd1..75a0fd43e8b 100644 --- a/clang/lib/CodeGen/CGClass.cpp +++ b/clang/lib/CodeGen/CGClass.cpp @@ -2604,28 +2604,34 @@ void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD, !CGM.HasHiddenLTOVisibility(RD)) return; - std::string TypeName = RD->getQualifiedNameAsString(); - if (getContext().getSanitizerBlacklist().isBlacklistedType(TypeName)) - return; - - SanitizerScope SanScope(this); + SanitizerMask M; llvm::SanitizerStatKind SSK; switch (TCK) { case CFITCK_VCall: + M = SanitizerKind::CFIVCall; SSK = llvm::SanStat_CFI_VCall; break; case CFITCK_NVCall: + M = SanitizerKind::CFINVCall; SSK = llvm::SanStat_CFI_NVCall; break; case CFITCK_DerivedCast: + M = SanitizerKind::CFIDerivedCast; SSK = llvm::SanStat_CFI_DerivedCast; break; case CFITCK_UnrelatedCast: + M = SanitizerKind::CFIUnrelatedCast; SSK = llvm::SanStat_CFI_UnrelatedCast; break; case CFITCK_ICall: llvm_unreachable("not expecting CFITCK_ICall"); } + + std::string TypeName = RD->getQualifiedNameAsString(); + if (getContext().getSanitizerBlacklist().isBlacklistedType(M, TypeName)) + return; + + SanitizerScope SanScope(this); EmitSanitizerStatReport(SSK); llvm::Metadata *MD = @@ -2636,24 +2642,6 @@ void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD, llvm::Value *TypeTest = Builder.CreateCall( CGM.getIntrinsic(llvm::Intrinsic::type_test), {CastedVTable, TypeId}); - SanitizerMask M; - switch (TCK) { - case CFITCK_VCall: - M = SanitizerKind::CFIVCall; - break; - case CFITCK_NVCall: - M = SanitizerKind::CFINVCall; - break; - case CFITCK_DerivedCast: - M = SanitizerKind::CFIDerivedCast; - break; - case CFITCK_UnrelatedCast: - M = SanitizerKind::CFIUnrelatedCast; - break; - case CFITCK_ICall: - llvm_unreachable("not expecting CFITCK_ICall"); - } - llvm::Constant *StaticData[] = { llvm::ConstantInt::get(Int8Ty, TCK), EmitCheckSourceLocation(Loc), @@ -2688,7 +2676,8 @@ bool CodeGenFunction::ShouldEmitVTableTypeCheckedLoad(const CXXRecordDecl *RD) { return false; std::string TypeName = RD->getQualifiedNameAsString(); - return !getContext().getSanitizerBlacklist().isBlacklistedType(TypeName); + return !getContext().getSanitizerBlacklist().isBlacklistedType( + SanitizerKind::CFIVCall, TypeName); } llvm::Value *CodeGenFunction::EmitVTableTypeCheckedLoad( diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp index 4db207cc2da..e3437eb9367 100644 --- a/clang/lib/CodeGen/CGDeclCXX.cpp +++ b/clang/lib/CodeGen/CGDeclCXX.cpp @@ -316,17 +316,25 @@ llvm::Function *CodeGenModule::CreateGlobalInitOrDestructFunction( if (!getLangOpts().Exceptions) Fn->setDoesNotThrow(); - if (!isInSanitizerBlacklist(Fn, Loc)) { - if (getLangOpts().Sanitize.hasOneOf(SanitizerKind::Address | - SanitizerKind::KernelAddress)) - Fn->addFnAttr(llvm::Attribute::SanitizeAddress); - if (getLangOpts().Sanitize.has(SanitizerKind::Thread)) - Fn->addFnAttr(llvm::Attribute::SanitizeThread); - if (getLangOpts().Sanitize.has(SanitizerKind::Memory)) - Fn->addFnAttr(llvm::Attribute::SanitizeMemory); - if (getLangOpts().Sanitize.has(SanitizerKind::SafeStack)) - Fn->addFnAttr(llvm::Attribute::SafeStack); - } + if (getLangOpts().Sanitize.has(SanitizerKind::Address) && + !isInSanitizerBlacklist(SanitizerKind::Address, Fn, Loc)) + Fn->addFnAttr(llvm::Attribute::SanitizeAddress); + + if (getLangOpts().Sanitize.has(SanitizerKind::KernelAddress) && + !isInSanitizerBlacklist(SanitizerKind::KernelAddress, Fn, Loc)) + Fn->addFnAttr(llvm::Attribute::SanitizeAddress); + + if (getLangOpts().Sanitize.has(SanitizerKind::Thread) && + !isInSanitizerBlacklist(SanitizerKind::Thread, Fn, Loc)) + Fn->addFnAttr(llvm::Attribute::SanitizeThread); + + if (getLangOpts().Sanitize.has(SanitizerKind::Memory) && + !isInSanitizerBlacklist(SanitizerKind::Memory, Fn, Loc)) + Fn->addFnAttr(llvm::Attribute::SanitizeMemory); + + if (getLangOpts().Sanitize.has(SanitizerKind::SafeStack) && + !isInSanitizerBlacklist(SanitizerKind::SafeStack, Fn, Loc)) + Fn->addFnAttr(llvm::Attribute::SafeStack); return Fn; } diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp index 193e4f122af..cf3dc49ef2a 100644 --- a/clang/lib/CodeGen/CGExpr.cpp +++ b/clang/lib/CodeGen/CGExpr.cpp @@ -725,7 +725,7 @@ void CodeGenFunction::EmitTypeCheck(TypeCheckKind TCK, SourceLocation Loc, // Blacklist based on the mangled type. if (!CGM.getContext().getSanitizerBlacklist().isBlacklistedType( - Out.str())) { + SanitizerKind::Vptr, Out.str())) { llvm::hash_code TypeHash = hash_value(Out.str()); // Load the vptr, and compute hash_16_bytes(TypeHash, vptr). diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp index 1c9fc367940..53737d54651 100644 --- a/clang/lib/CodeGen/CodeGenFunction.cpp +++ b/clang/lib/CodeGen/CodeGenFunction.cpp @@ -804,8 +804,19 @@ void CodeGenFunction::StartFunction(GlobalDecl GD, CurFnInfo = &FnInfo; assert(CurFn->isDeclaration() && "Function already has body?"); - if (CGM.isInSanitizerBlacklist(Fn, Loc)) - SanOpts.clear(); + // If this function has been blacklisted for any of the enabled sanitizers, + // disable the sanitizer for the function. + do { +#define SANITIZER(NAME, ID) \ + if (SanOpts.empty()) \ + break; \ + if (SanOpts.has(SanitizerKind::ID)) \ + if (CGM.isInSanitizerBlacklist(SanitizerKind::ID, Fn, Loc)) \ + SanOpts.set(SanitizerKind::ID, false); + +#include "clang/Basic/Sanitizers.def" +#undef SANITIZER + } while (0); if (D) { // Apply the no_sanitize* attributes to SanOpts. diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp index 4903d408ada..a8cc50bdd64 100644 --- a/clang/lib/CodeGen/CodeGenModule.cpp +++ b/clang/lib/CodeGen/CodeGenModule.cpp @@ -1543,20 +1543,21 @@ void CodeGenModule::AddGlobalAnnotations(const ValueDecl *D, Annotations.push_back(EmitAnnotateAttr(GV, I, D->getLocation())); } -bool CodeGenModule::isInSanitizerBlacklist(llvm::Function *Fn, +bool CodeGenModule::isInSanitizerBlacklist(SanitizerMask Kind, + llvm::Function *Fn, SourceLocation Loc) const { const auto &SanitizerBL = getContext().getSanitizerBlacklist(); // Blacklist by function name. - if (SanitizerBL.isBlacklistedFunction(Fn->getName())) + if (SanitizerBL.isBlacklistedFunction(Kind, Fn->getName())) return true; // Blacklist by location. if (Loc.isValid()) - return SanitizerBL.isBlacklistedLocation(Loc); + return SanitizerBL.isBlacklistedLocation(Kind, Loc); // If location is unknown, this may be a compiler-generated function. Assume // it's located in the main file. auto &SM = Context.getSourceManager(); if (const auto *MainFile = SM.getFileEntryForID(SM.getMainFileID())) { - return SanitizerBL.isBlacklistedFile(MainFile->getName()); + return SanitizerBL.isBlacklistedFile(Kind, MainFile->getName()); } return false; } @@ -1565,13 +1566,14 @@ bool CodeGenModule::isInSanitizerBlacklist(llvm::GlobalVariable *GV, SourceLocation Loc, QualType Ty, StringRef Category) const { // For now globals can be blacklisted only in ASan and KASan. - if (!LangOpts.Sanitize.hasOneOf( - SanitizerKind::Address | SanitizerKind::KernelAddress)) + const SanitizerMask EnabledAsanMask = LangOpts.Sanitize.Mask & + (SanitizerKind::Address | SanitizerKind::KernelAddress); + if (!EnabledAsanMask) return false; const auto &SanitizerBL = getContext().getSanitizerBlacklist(); - if (SanitizerBL.isBlacklistedGlobal(GV->getName(), Category)) + if (SanitizerBL.isBlacklistedGlobal(EnabledAsanMask, GV->getName(), Category)) return true; - if (SanitizerBL.isBlacklistedLocation(Loc, Category)) + if (SanitizerBL.isBlacklistedLocation(EnabledAsanMask, Loc, Category)) return true; // Check global type. if (!Ty.isNull()) { @@ -1583,7 +1585,7 @@ bool CodeGenModule::isInSanitizerBlacklist(llvm::GlobalVariable *GV, // We allow to blacklist only record types (classes, structs etc.) if (Ty->isRecordType()) { std::string TypeStr = Ty.getAsString(getContext().getPrintingPolicy()); - if (SanitizerBL.isBlacklistedType(TypeStr, Category)) + if (SanitizerBL.isBlacklistedType(EnabledAsanMask, TypeStr, Category)) return true; } } diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h index 4bff296cb19..c2bc0e8b8b2 100644 --- a/clang/lib/CodeGen/CodeGenModule.h +++ b/clang/lib/CodeGen/CodeGenModule.h @@ -1106,7 +1106,8 @@ public: /// annotations are emitted during finalization of the LLVM code. void AddGlobalAnnotations(const ValueDecl *D, llvm::GlobalValue *GV); - bool isInSanitizerBlacklist(llvm::Function *Fn, SourceLocation Loc) const; + bool isInSanitizerBlacklist(SanitizerMask Kind, llvm::Function *Fn, + SourceLocation Loc) const; bool isInSanitizerBlacklist(llvm::GlobalVariable *GV, SourceLocation Loc, QualType Ty, |