r220097 - [ASan] Improve blacklisting of global variables.
Alexey Samsonov
vonosmas at gmail.com
Fri Oct 17 15:37:33 PDT 2014
Author: samsonov
Date: Fri Oct 17 17:37:33 2014
New Revision: 220097
URL: http://llvm.org/viewvc/llvm-project?rev=220097&view=rev
Log:
[ASan] Improve blacklisting of global variables.
This commit changes the way we blacklist global variables in ASan.
Now the global is excluded from instrumentation (either regular
bounds checking, or initialization-order checking) if:
1) Global is explicitly blacklisted by its mangled name.
This part is left unchanged.
2) SourceLocation of a global is in blacklisted source file.
This changes the old behavior, where instead of looking at the
SourceLocation of a variable we simply considered llvm::Module
identifier. This was wrong, as identifier may not correspond to
the file name, and we incorrectly disabled instrumentation
for globals coming from #include'd files.
3) Global is blacklisted by type.
Now we build the type of a global variable using Clang machinery
(QualType::getAsString()), instead of llvm::StructType::getName().
After this commit, the active users of ASan blacklist files
may have to revisit them (this is a backwards-incompatible change).
Modified:
cfe/trunk/docs/AddressSanitizer.rst
cfe/trunk/include/clang/Basic/SanitizerBlacklist.h
cfe/trunk/lib/Basic/SanitizerBlacklist.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.cpp
cfe/trunk/lib/CodeGen/CodeGenModule.h
cfe/trunk/lib/CodeGen/SanitizerMetadata.cpp
cfe/trunk/lib/CodeGen/SanitizerMetadata.h
cfe/trunk/test/CodeGen/asan-globals.cpp
cfe/trunk/test/CodeGen/sanitize-init-order.cpp
Modified: cfe/trunk/docs/AddressSanitizer.rst
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/docs/AddressSanitizer.rst?rev=220097&r1=220096&r2=220097&view=diff
==============================================================================
--- cfe/trunk/docs/AddressSanitizer.rst (original)
+++ cfe/trunk/docs/AddressSanitizer.rst Fri Oct 17 17:37:33 2014
@@ -165,9 +165,9 @@ problems happening in certain source fil
# Disable out-of-bound checks for global:
global:bad_array
# Disable out-of-bound checks for global instances of a given class ...
- type:class.Namespace::BadClassName
+ type:Namespace::BadClassName
# ... or a given struct. Use wildcard to deal with anonymous namespace.
- type:struct.Namespace2::*::BadStructName
+ type:Namespace2::*::BadStructName
# Disable initialization-order checks for globals:
global:bad_init_global=init
type:*BadInitClassSubstring*=init
Modified: cfe/trunk/include/clang/Basic/SanitizerBlacklist.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/SanitizerBlacklist.h?rev=220097&r1=220096&r2=220097&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/SanitizerBlacklist.h (original)
+++ cfe/trunk/include/clang/Basic/SanitizerBlacklist.h Fri Oct 17 17:37:33 2014
@@ -21,10 +21,6 @@
#include "llvm/Support/SpecialCaseList.h"
#include <memory>
-namespace llvm {
-class GlobalVariable;
-}
-
namespace clang {
class SanitizerBlacklist {
@@ -33,8 +29,8 @@ class SanitizerBlacklist {
public:
SanitizerBlacklist(StringRef BlacklistPath, SourceManager &SM);
- bool isIn(const llvm::GlobalVariable &G,
- StringRef Category = StringRef()) const;
+ bool isBlacklistedGlobal(StringRef GlobalName,
+ StringRef Category = StringRef()) const;
bool isBlacklistedType(StringRef MangledTypeName,
StringRef Category = StringRef()) const;
bool isBlacklistedFunction(StringRef FunctionName) const;
Modified: cfe/trunk/lib/Basic/SanitizerBlacklist.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Basic/SanitizerBlacklist.cpp?rev=220097&r1=220096&r2=220097&view=diff
==============================================================================
--- cfe/trunk/lib/Basic/SanitizerBlacklist.cpp (original)
+++ cfe/trunk/lib/Basic/SanitizerBlacklist.cpp Fri Oct 17 17:37:33 2014
@@ -12,31 +12,16 @@
//
//===----------------------------------------------------------------------===//
#include "clang/Basic/SanitizerBlacklist.h"
-#include "llvm/IR/GlobalValue.h"
-#include "llvm/IR/Module.h"
using namespace clang;
-static StringRef GetGlobalTypeString(const llvm::GlobalValue &G) {
- // Types of GlobalVariables are always pointer types.
- llvm::Type *GType = G.getType()->getElementType();
- // For now we support blacklisting struct types only.
- if (llvm::StructType *SGType = dyn_cast<llvm::StructType>(GType)) {
- if (!SGType->isLiteral())
- return SGType->getName();
- }
- return "<unknown type>";
-}
-
SanitizerBlacklist::SanitizerBlacklist(StringRef BlacklistPath,
SourceManager &SM)
: SCL(llvm::SpecialCaseList::createOrDie(BlacklistPath)), SM(SM) {}
-bool SanitizerBlacklist::isIn(const llvm::GlobalVariable &G,
- StringRef Category) const {
- return isBlacklistedFile(G.getParent()->getModuleIdentifier(), Category) ||
- SCL->inSection("global", G.getName(), Category) ||
- SCL->inSection("type", GetGlobalTypeString(G), Category);
+bool SanitizerBlacklist::isBlacklistedGlobal(StringRef GlobalName,
+ StringRef Category) const {
+ return SCL->inSection("global", GlobalName, Category);
}
bool SanitizerBlacklist::isBlacklistedType(StringRef MangledTypeName,
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.cpp?rev=220097&r1=220096&r2=220097&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.cpp (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.cpp Fri Oct 17 17:37:33 2014
@@ -1186,6 +1186,34 @@ bool CodeGenModule::isInSanitizerBlackli
return false;
}
+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.Address)
+ return false;
+ const auto &SanitizerBL = getContext().getSanitizerBlacklist();
+ if (SanitizerBL.isBlacklistedGlobal(GV->getName(), Category))
+ return true;
+ if (SanitizerBL.isBlacklistedLocation(Loc, Category))
+ return true;
+ // Check global type.
+ if (!Ty.isNull()) {
+ // Drill down the array types: if global variable of a fixed type is
+ // blacklisted, we also don't instrument arrays of them.
+ while (auto AT = dyn_cast<ArrayType>(Ty.getTypePtr()))
+ Ty = AT->getElementType();
+ Ty = Ty.getCanonicalType().getUnqualifiedType();
+ // 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))
+ return true;
+ }
+ }
+ return false;
+}
+
bool CodeGenModule::MayDeferGeneration(const ValueDecl *Global) {
// Never defer when EmitAllDecls is specified.
if (LangOpts.EmitAllDecls)
@@ -2800,7 +2828,8 @@ CodeGenModule::GetAddrOfConstantStringFr
if (Entry)
*Entry = GV;
- SanitizerMD->reportGlobalToASan(GV, S->getStrTokenLoc(0), "<string literal>");
+ SanitizerMD->reportGlobalToASan(GV, S->getStrTokenLoc(0), "<string literal>",
+ QualType());
return GV;
}
Modified: cfe/trunk/lib/CodeGen/CodeGenModule.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenModule.h?rev=220097&r1=220096&r2=220097&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenModule.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenModule.h Fri Oct 17 17:37:33 2014
@@ -1048,6 +1048,10 @@ public:
bool isInSanitizerBlacklist(llvm::Function *Fn, SourceLocation Loc) const;
+ bool isInSanitizerBlacklist(llvm::GlobalVariable *GV, SourceLocation Loc,
+ QualType Ty,
+ StringRef Category = StringRef()) const;
+
SanitizerMetadata *getSanitizerMetadata() {
return SanitizerMD.get();
}
Modified: cfe/trunk/lib/CodeGen/SanitizerMetadata.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/SanitizerMetadata.cpp?rev=220097&r1=220096&r2=220097&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/SanitizerMetadata.cpp (original)
+++ cfe/trunk/lib/CodeGen/SanitizerMetadata.cpp Fri Oct 17 17:37:33 2014
@@ -12,6 +12,7 @@
//===----------------------------------------------------------------------===//
#include "SanitizerMetadata.h"
#include "CodeGenModule.h"
+#include "clang/AST/Type.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/IR/Constants.h"
@@ -22,11 +23,12 @@ SanitizerMetadata::SanitizerMetadata(Cod
void SanitizerMetadata::reportGlobalToASan(llvm::GlobalVariable *GV,
SourceLocation Loc, StringRef Name,
- bool IsDynInit, bool IsBlacklisted) {
+ QualType Ty, bool IsDynInit,
+ bool IsBlacklisted) {
if (!CGM.getLangOpts().Sanitize.Address)
return;
- IsDynInit &= !CGM.getContext().getSanitizerBlacklist().isIn(*GV, "init");
- IsBlacklisted |= CGM.getContext().getSanitizerBlacklist().isIn(*GV);
+ IsDynInit &= !CGM.isInSanitizerBlacklist(GV, Loc, Ty, "init");
+ IsBlacklisted |= CGM.isInSanitizerBlacklist(GV, Loc, Ty);
llvm::Value *LocDescr = nullptr;
llvm::Value *GlobalName = nullptr;
@@ -57,14 +59,14 @@ void SanitizerMetadata::reportGlobalToAS
std::string QualName;
llvm::raw_string_ostream OS(QualName);
D.printQualifiedName(OS);
- reportGlobalToASan(GV, D.getLocation(), OS.str(), IsDynInit);
+ reportGlobalToASan(GV, D.getLocation(), OS.str(), D.getType(), IsDynInit);
}
void SanitizerMetadata::disableSanitizerForGlobal(llvm::GlobalVariable *GV) {
// For now, just make sure the global is not modified by the ASan
// instrumentation.
if (CGM.getLangOpts().Sanitize.Address)
- reportGlobalToASan(GV, SourceLocation(), "", false, true);
+ reportGlobalToASan(GV, SourceLocation(), "", QualType(), false, true);
}
void SanitizerMetadata::disableSanitizerForInstruction(llvm::Instruction *I) {
Modified: cfe/trunk/lib/CodeGen/SanitizerMetadata.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/SanitizerMetadata.h?rev=220097&r1=220096&r2=220097&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/SanitizerMetadata.h (original)
+++ cfe/trunk/lib/CodeGen/SanitizerMetadata.h Fri Oct 17 17:37:33 2014
@@ -15,6 +15,7 @@
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
+#include "clang/AST/Type.h"
namespace llvm {
class GlobalVariable;
@@ -39,7 +40,7 @@ public:
void reportGlobalToASan(llvm::GlobalVariable *GV, const VarDecl &D,
bool IsDynInit = false);
void reportGlobalToASan(llvm::GlobalVariable *GV, SourceLocation Loc,
- StringRef Name, bool IsDynInit = false,
+ StringRef Name, QualType Ty, bool IsDynInit = false,
bool IsBlacklisted = false);
void disableSanitizerForGlobal(llvm::GlobalVariable *GV);
void disableSanitizerForInstruction(llvm::Instruction *I);
Modified: cfe/trunk/test/CodeGen/asan-globals.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/asan-globals.cpp?rev=220097&r1=220096&r2=220097&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/asan-globals.cpp (original)
+++ cfe/trunk/test/CodeGen/asan-globals.cpp Fri Oct 17 17:37:33 2014
@@ -1,7 +1,8 @@
+// RUN: echo "int extra_global;" > %t.extra-source.cpp
// RUN: echo "global:*blacklisted_global*" > %t.blacklist
-// RUN: %clang_cc1 -fsanitize=address -fsanitize-blacklist=%t.blacklist -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -include %t.extra-source.cpp -fsanitize=address -fsanitize-blacklist=%t.blacklist -emit-llvm -o - %s | FileCheck %s
// RUN: echo "src:%s" > %t.blacklist-src
-// RUN: %clang_cc1 -fsanitize=address -fsanitize-blacklist=%t.blacklist-src -emit-llvm -o - %s | FileCheck %s --check-prefix=BLACKLIST-SRC
+// RUN: %clang_cc1 -include %t.extra-source.cpp -fsanitize=address -fsanitize-blacklist=%t.blacklist-src -emit-llvm -o - %s | FileCheck %s --check-prefix=BLACKLIST-SRC
// REQUIRES: shell
int global;
@@ -13,18 +14,22 @@ void func() {
const char *literal = "Hello, world!";
}
-// CHECK: !llvm.asan.globals = !{![[GLOBAL:[0-9]+]], ![[DYN_INIT_GLOBAL:[0-9]+]], ![[BLACKLISTED_GLOBAL:[0-9]+]], ![[STATIC_VAR:[0-9]+]], ![[LITERAL:[0-9]+]]}
+// CHECK: !llvm.asan.globals = !{![[EXTRA_GLOBAL:[0-9]+]], ![[GLOBAL:[0-9]+]], ![[DYN_INIT_GLOBAL:[0-9]+]], ![[BLACKLISTED_GLOBAL:[0-9]+]], ![[STATIC_VAR:[0-9]+]], ![[LITERAL:[0-9]+]]}
+// CHECK: ![[EXTRA_GLOBAL]] = metadata !{{{.*}} metadata ![[EXTRA_GLOBAL_LOC:[0-9]+]], metadata !"extra_global", i1 false, i1 false}
+// CHECK: ![[EXTRA_GLOBAL_LOC]] = metadata !{metadata !"{{.*}}extra-source.cpp", i32 1, i32 5}
// CHECK: ![[GLOBAL]] = metadata !{{{.*}} metadata ![[GLOBAL_LOC:[0-9]+]], metadata !"global", i1 false, i1 false}
-// CHECK: ![[GLOBAL_LOC]] = metadata !{metadata !"{{.*}}asan-globals.cpp", i32 7, i32 5}
+// CHECK: ![[GLOBAL_LOC]] = metadata !{metadata !"{{.*}}asan-globals.cpp", i32 8, i32 5}
// CHECK: ![[DYN_INIT_GLOBAL]] = metadata !{{{.*}} metadata ![[DYN_INIT_LOC:[0-9]+]], metadata !"dyn_init_global", i1 true, i1 false}
-// CHECK: ![[DYN_INIT_LOC]] = metadata !{metadata !"{{.*}}asan-globals.cpp", i32 8, i32 5}
+// CHECK: ![[DYN_INIT_LOC]] = metadata !{metadata !"{{.*}}asan-globals.cpp", i32 9, i32 5}
// CHECK: ![[BLACKLISTED_GLOBAL]] = metadata !{{{.*}}, null, null, i1 false, i1 true}
// CHECK: ![[STATIC_VAR]] = metadata !{{{.*}} metadata ![[STATIC_LOC:[0-9]+]], metadata !"static_var", i1 false, i1 false}
-// CHECK: ![[STATIC_LOC]] = metadata !{metadata !"{{.*}}asan-globals.cpp", i32 12, i32 14}
+// CHECK: ![[STATIC_LOC]] = metadata !{metadata !"{{.*}}asan-globals.cpp", i32 13, i32 14}
// CHECK: ![[LITERAL]] = metadata !{{{.*}} metadata ![[LITERAL_LOC:[0-9]+]], metadata !"<string literal>", i1 false, i1 false}
-// CHECK: ![[LITERAL_LOC]] = metadata !{metadata !"{{.*}}asan-globals.cpp", i32 13, i32 25}
+// CHECK: ![[LITERAL_LOC]] = metadata !{metadata !"{{.*}}asan-globals.cpp", i32 14, i32 25}
-// BLACKLIST-SRC: !llvm.asan.globals = !{![[GLOBAL:[0-9]+]], ![[DYN_INIT_GLOBAL:[0-9]+]], ![[BLACKLISTED_GLOBAL:[0-9]+]], ![[STATIC_VAR:[0-9]+]], ![[LITERAL:[0-9]+]]}
+// BLACKLIST-SRC: !llvm.asan.globals = !{![[EXTRA_GLOBAL:[0-9]+]], ![[GLOBAL:[0-9]+]], ![[DYN_INIT_GLOBAL:[0-9]+]], ![[BLACKLISTED_GLOBAL:[0-9]+]], ![[STATIC_VAR:[0-9]+]], ![[LITERAL:[0-9]+]]}
+// BLACKLIST-SRC: ![[EXTRA_GLOBAL]] = metadata !{{{.*}} metadata ![[EXTRA_GLOBAL_LOC:[0-9]+]], metadata !"extra_global", i1 false, i1 false}
+// BLACKLIST-SRC: ![[EXTRA_GLOBAL_LOC]] = metadata !{metadata !"{{.*}}extra-source.cpp", i32 1, i32 5}
// BLACKLIST-SRC: ![[GLOBAL]] = metadata !{{{.*}} null, null, i1 false, i1 true}
// BLACKLIST-SRC: ![[DYN_INIT_GLOBAL]] = metadata !{{{.*}} null, null, i1 true, i1 true}
// BLACKLIST-SRC: ![[BLACKLISTED_GLOBAL]] = metadata !{{{.*}}, null, null, i1 false, i1 true}
Modified: cfe/trunk/test/CodeGen/sanitize-init-order.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/sanitize-init-order.cpp?rev=220097&r1=220096&r2=220097&view=diff
==============================================================================
--- cfe/trunk/test/CodeGen/sanitize-init-order.cpp (original)
+++ cfe/trunk/test/CodeGen/sanitize-init-order.cpp Fri Oct 17 17:37:33 2014
@@ -2,7 +2,8 @@
// Test blacklist functionality.
// RUN: echo "global-init-src:%s" > %t-file.blacklist
-// RUN: echo "global-init-type:struct.PODWithCtorAndDtor" > %t-type.blacklist
+// RUN: echo "global-init-type:PODWithCtorAndDtor" > %t-type.blacklist
+// RUN: echo "type:NS::PODWithCtor=init" >> %t-type.blacklist
// RUN: %clang_cc1 -fsanitize=address -fsanitize-blacklist=%t-file.blacklist -emit-llvm -o - %s | FileCheck %s --check-prefix=BLACKLIST
// RUN: %clang_cc1 -fsanitize=address -fsanitize-blacklist=%t-type.blacklist -emit-llvm -o - %s | FileCheck %s --check-prefix=BLACKLIST
// REQUIRES: shell
@@ -25,14 +26,25 @@ struct PODWithCtorAndDtor {
};
PODWithCtorAndDtor s3;
+namespace NS {
+class PODWithCtor {
+public:
+ PODWithCtor() {}
+};
+
+const volatile PODWithCtor array[5][5];
+}
+
// Check that ASan init-order checking ignores structs with trivial default
// constructor.
-// CHECK: !llvm.asan.globals = !{![[GLOB_1:[0-9]+]], ![[GLOB_2:[0-9]+]], ![[GLOB_3:[0-9]]]}
+// CHECK: !llvm.asan.globals = !{![[GLOB_1:[0-9]+]], ![[GLOB_2:[0-9]+]], ![[GLOB_3:[0-9]]], ![[GLOB_4:[0-9]]]}
// CHECK: ![[GLOB_1]] = metadata !{%struct.PODStruct* {{.*}}, i1 false, i1 false}
// CHECK: ![[GLOB_2]] = metadata !{%struct.PODWithDtor* {{.*}}, i1 false, i1 false}
// CHECK: ![[GLOB_3]] = metadata !{%struct.PODWithCtorAndDtor* {{.*}}, i1 true, i1 false}
+// CHECK: ![[GLOB_4]] = metadata !{{{.*}}class.NS::PODWithCtor{{.*}}, i1 true, i1 false}
-// BLACKLIST: !llvm.asan.globals = !{![[GLOB_1:[0-9]+]], ![[GLOB_2:[0-9]+]], ![[GLOB_3:[0-9]]]}
+// BLACKLIST: !llvm.asan.globals = !{![[GLOB_1:[0-9]+]], ![[GLOB_2:[0-9]+]], ![[GLOB_3:[0-9]]], ![[GLOB_4:[0-9]]]}
// BLACKLIST: ![[GLOB_1]] = metadata !{%struct.PODStruct* {{.*}}, i1 false, i1 false}
// BLACKLIST: ![[GLOB_2]] = metadata !{%struct.PODWithDtor* {{.*}}, i1 false, i1 false}
// BLACKLIST: ![[GLOB_3]] = metadata !{%struct.PODWithCtorAndDtor* {{.*}}, i1 false, i1 false}
+// BLACKLIST: ![[GLOB_4]] = metadata !{{{.*}}class.NS::PODWithCtor{{.*}}, i1 false, i1 false}
More information about the cfe-commits
mailing list