summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorAlexander Potapenko <glider@google.com>2015-06-19 12:19:07 +0000
committerAlexander Potapenko <glider@google.com>2015-06-19 12:19:07 +0000
commitb9b73ef9067371fbe78c34e0f3b23d014413a2f8 (patch)
tree879cacb4b816acf453a145cdec863e6150070ece /clang/lib
parent284a750c5ff95a29cd8cc9130d3eb7ec6d25e352 (diff)
downloadbcm5719-llvm-b9b73ef9067371fbe78c34e0f3b23d014413a2f8.tar.gz
bcm5719-llvm-b9b73ef9067371fbe78c34e0f3b23d014413a2f8.zip
[ASan] Initial support for Kernel AddressSanitizer
This patch adds initial support for the -fsanitize=kernel-address flag to Clang. Right now it's quite restricted: only out-of-line instrumentation is supported, globals are not instrumented, some GCC kasan flags are not supported. Using this patch I am able to build and boot the KASan tree with LLVMLinux patches from github.com/ramosian-glider/kasan/tree/kasan_llvmlinux. To disable KASan instrumentation for a certain function attribute((no_sanitize("kernel-address"))) can be used. llvm-svn: 240131
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/Decl.cpp3
-rw-r--r--clang/lib/Basic/Sanitizers.cpp4
-rw-r--r--clang/lib/CodeGen/BackendUtil.cpp17
-rw-r--r--clang/lib/CodeGen/CGDeclCXX.cpp3
-rw-r--r--clang/lib/CodeGen/CodeGenFunction.cpp2
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp5
-rw-r--r--clang/lib/CodeGen/SanitizerMetadata.cpp9
-rw-r--r--clang/lib/Driver/SanitizerArgs.cpp5
-rw-r--r--clang/lib/Lex/PPMacroExpansion.cpp4
9 files changed, 40 insertions, 12 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 8eff4c4427b..d9a3389c58f 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -3681,7 +3681,8 @@ void RecordDecl::LoadFieldsFromExternalStorage() const {
bool RecordDecl::mayInsertExtraPadding(bool EmitRemark) const {
ASTContext &Context = getASTContext();
- if (!Context.getLangOpts().Sanitize.has(SanitizerKind::Address) ||
+ if (!Context.getLangOpts().Sanitize.hasOneOf(
+ SanitizerKind::Address | SanitizerKind::KernelAddress) ||
!Context.getLangOpts().SanitizeAddressFieldPadding)
return false;
const auto &Blacklist = Context.getSanitizerBlacklist();
diff --git a/clang/lib/Basic/Sanitizers.cpp b/clang/lib/Basic/Sanitizers.cpp
index 8c4884b8ec3..d3676b6b465 100644
--- a/clang/lib/Basic/Sanitizers.cpp
+++ b/clang/lib/Basic/Sanitizers.cpp
@@ -25,6 +25,10 @@ bool SanitizerSet::has(SanitizerMask K) const {
return Mask & K;
}
+bool SanitizerSet::hasOneOf(SanitizerMask K) const {
+ return Mask & K;
+}
+
void SanitizerSet::set(SanitizerMask K, bool Value) {
assert(llvm::countPopulation(K) == 1);
Mask = Value ? (Mask | K) : (Mask & ~K);
diff --git a/clang/lib/CodeGen/BackendUtil.cpp b/clang/lib/CodeGen/BackendUtil.cpp
index 30e9ebffa28..f5edea7810a 100644
--- a/clang/lib/CodeGen/BackendUtil.cpp
+++ b/clang/lib/CodeGen/BackendUtil.cpp
@@ -201,8 +201,14 @@ static void addSanitizerCoveragePass(const PassManagerBuilder &Builder,
static void addAddressSanitizerPasses(const PassManagerBuilder &Builder,
legacy::PassManagerBase &PM) {
- PM.add(createAddressSanitizerFunctionPass());
- PM.add(createAddressSanitizerModulePass());
+ PM.add(createAddressSanitizerFunctionPass(/*CompileKernel*/false));
+ PM.add(createAddressSanitizerModulePass(/*CompileKernel*/false));
+}
+
+static void addKernelAddressSanitizerPasses(const PassManagerBuilder &Builder,
+ legacy::PassManagerBase &PM) {
+ PM.add(createAddressSanitizerFunctionPass(/*CompileKernel*/true));
+ PM.add(createAddressSanitizerModulePass(/*CompileKernel*/true));
}
static void addMemorySanitizerPass(const PassManagerBuilder &Builder,
@@ -328,6 +334,13 @@ void EmitAssemblyHelper::CreatePasses() {
addAddressSanitizerPasses);
}
+ if (LangOpts.Sanitize.has(SanitizerKind::KernelAddress)) {
+ PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
+ addKernelAddressSanitizerPasses);
+ PMBuilder.addExtension(PassManagerBuilder::EP_EnabledOnOptLevel0,
+ addKernelAddressSanitizerPasses);
+ }
+
if (LangOpts.Sanitize.has(SanitizerKind::Memory)) {
PMBuilder.addExtension(PassManagerBuilder::EP_OptimizerLast,
addMemorySanitizerPass);
diff --git a/clang/lib/CodeGen/CGDeclCXX.cpp b/clang/lib/CodeGen/CGDeclCXX.cpp
index 50a499607f8..bae8ab4ea0d 100644
--- a/clang/lib/CodeGen/CGDeclCXX.cpp
+++ b/clang/lib/CodeGen/CGDeclCXX.cpp
@@ -267,7 +267,8 @@ llvm::Function *CodeGenModule::CreateGlobalInitOrDestructFunction(
Fn->setDoesNotThrow();
if (!isInSanitizerBlacklist(Fn, Loc)) {
- if (getLangOpts().Sanitize.has(SanitizerKind::Address))
+ if (getLangOpts().Sanitize.hasOneOf(SanitizerKind::Address |
+ SanitizerKind::KernelAddress))
Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
if (getLangOpts().Sanitize.has(SanitizerKind::Thread))
Fn->addFnAttr(llvm::Attribute::SanitizeThread);
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index f370ac27676..bece41e9ecb 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -615,7 +615,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,
}
// Apply sanitizer attributes to the function.
- if (SanOpts.has(SanitizerKind::Address))
+ if (SanOpts.hasOneOf(SanitizerKind::Address | SanitizerKind::KernelAddress))
Fn->addFnAttr(llvm::Attribute::SanitizeAddress);
if (SanOpts.has(SanitizerKind::Thread))
Fn->addFnAttr(llvm::Attribute::SanitizeThread);
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index c0cbe98484f..2dd5414795e 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1218,8 +1218,9 @@ bool CodeGenModule::isInSanitizerBlacklist(llvm::Function *Fn,
bool CodeGenModule::isInSanitizerBlacklist(llvm::GlobalVariable *GV,
SourceLocation Loc, QualType Ty,
StringRef Category) const {
- // For now globals can be blacklisted only in ASan.
- if (!LangOpts.Sanitize.has(SanitizerKind::Address))
+ // For now globals can be blacklisted only in ASan and KASan.
+ if (!LangOpts.Sanitize.hasOneOf(
+ SanitizerKind::Address | SanitizerKind::KernelAddress))
return false;
const auto &SanitizerBL = getContext().getSanitizerBlacklist();
if (SanitizerBL.isBlacklistedGlobal(GV->getName(), Category))
diff --git a/clang/lib/CodeGen/SanitizerMetadata.cpp b/clang/lib/CodeGen/SanitizerMetadata.cpp
index 7c38b2807e9..2a338bac4b4 100644
--- a/clang/lib/CodeGen/SanitizerMetadata.cpp
+++ b/clang/lib/CodeGen/SanitizerMetadata.cpp
@@ -25,7 +25,8 @@ void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV,
SourceLocation Loc, StringRef Name,
QualType Ty, bool IsDynInit,
bool IsBlacklisted) {
- if (!CGM.getLangOpts().Sanitize.has(SanitizerKind::Address))
+ if (!CGM.getLangOpts().Sanitize.hasOneOf(SanitizerKind::Address |
+ SanitizerKind::KernelAddress))
return;
IsDynInit &= !CGM.isInSanitizerBlacklist(GV, Loc, Ty, "init");
IsBlacklisted |= CGM.isInSanitizerBlacklist(GV, Loc, Ty);
@@ -56,7 +57,8 @@ void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV,
void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV,
const VarDecl &D, bool IsDynInit) {
- if (!CGM.getLangOpts().Sanitize.has(SanitizerKind::Address))
+ if (!CGM.getLangOpts().Sanitize.hasOneOf(SanitizerKind::Address |
+ SanitizerKind::KernelAddress))
return;
std::string QualName;
llvm::raw_string_ostream OS(QualName);
@@ -67,7 +69,8 @@ void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV,
void SanitizerMetadata::disableSanitizerForGlobal(llvm::GlobalVariable *GV) {
// For now, just make sure the global is not modified by the ASan
// instrumentation.
- if (CGM.getLangOpts().Sanitize.has(SanitizerKind::Address))
+ if (CGM.getLangOpts().Sanitize.hasOneOf(SanitizerKind::Address |
+ SanitizerKind::KernelAddress))
reportGlobalToASan(GV, SourceLocation(), "", QualType(), false, true);
}
diff --git a/clang/lib/Driver/SanitizerArgs.cpp b/clang/lib/Driver/SanitizerArgs.cpp
index 9918fcbd5e1..4d27a393182 100644
--- a/clang/lib/Driver/SanitizerArgs.cpp
+++ b/clang/lib/Driver/SanitizerArgs.cpp
@@ -305,7 +305,10 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
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(Leak, Memory), std::make_pair(KernelAddress, Address),
+ std::make_pair(KernelAddress, Leak),
+ std::make_pair(KernelAddress, Thread),
+ std::make_pair(KernelAddress, Memory)};
for (auto G : IncompatibleGroups) {
SanitizerMask Group = G.first;
if (Kinds & Group) {
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index c63cafb6d79..ccfb30240b0 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -1049,7 +1049,9 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
Feature = Feature.substr(2, Feature.size() - 4);
return llvm::StringSwitch<bool>(Feature)
- .Case("address_sanitizer", LangOpts.Sanitize.has(SanitizerKind::Address))
+ .Case("address_sanitizer",
+ LangOpts.Sanitize.hasOneOf(SanitizerKind::Address |
+ SanitizerKind::KernelAddress))
.Case("attribute_analyzer_noreturn", true)
.Case("attribute_availability", true)
.Case("attribute_availability_with_message", true)
OpenPOWER on IntegriCloud