From 590f279c456bbde632eca8ef89a85c478f15a249 Mon Sep 17 00:00:00 2001 From: Jan Korous Date: Fri, 8 Nov 2019 10:40:27 -0800 Subject: [PATCH] [clang] Add VFS support for sanitizers' blacklists Differential Revision: https://reviews.llvm.org/D69648 --- .../clang/Basic/SanitizerSpecialCaseList.h | 7 ++-- clang/lib/Basic/SanitizerBlacklist.cpp | 4 ++- clang/lib/Basic/SanitizerSpecialCaseList.cpp | 8 +++-- .../sanitizer-blacklist-vfsoverlay.yaml | 15 ++++++++ clang/test/CodeGen/ubsan-blacklist-vfs.c | 36 +++++++++++++++++++ llvm/include/llvm/Support/SpecialCaseList.h | 5 +-- llvm/lib/Support/SpecialCaseList.cpp | 4 +-- 7 files changed, 69 insertions(+), 10 deletions(-) create mode 100644 clang/test/CodeGen/Inputs/sanitizer-blacklist-vfsoverlay.yaml create mode 100644 clang/test/CodeGen/ubsan-blacklist-vfs.c diff --git a/clang/include/clang/Basic/SanitizerSpecialCaseList.h b/clang/include/clang/Basic/SanitizerSpecialCaseList.h index fb0db32c442f..88d31a6cbcce 100644 --- a/clang/include/clang/Basic/SanitizerSpecialCaseList.h +++ b/clang/include/clang/Basic/SanitizerSpecialCaseList.h @@ -17,6 +17,7 @@ #include "clang/Basic/Sanitizers.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/SpecialCaseList.h" +#include "llvm/Support/VirtualFileSystem.h" #include namespace clang { @@ -24,10 +25,12 @@ namespace clang { class SanitizerSpecialCaseList : public llvm::SpecialCaseList { public: static std::unique_ptr - create(const std::vector &Paths, std::string &Error); + create(const std::vector &Paths, llvm::vfs::FileSystem &VFS, + std::string &Error); static std::unique_ptr - createOrDie(const std::vector &Paths); + createOrDie(const std::vector &Paths, + llvm::vfs::FileSystem &VFS); // Query blacklisted entries if any bit in Mask matches the entry's section. bool inSection(SanitizerMask Mask, StringRef Prefix, StringRef Query, diff --git a/clang/lib/Basic/SanitizerBlacklist.cpp b/clang/lib/Basic/SanitizerBlacklist.cpp index aec35c7d9864..4f71349350fd 100644 --- a/clang/lib/Basic/SanitizerBlacklist.cpp +++ b/clang/lib/Basic/SanitizerBlacklist.cpp @@ -16,7 +16,9 @@ using namespace clang; SanitizerBlacklist::SanitizerBlacklist( const std::vector &BlacklistPaths, SourceManager &SM) - : SSCL(SanitizerSpecialCaseList::createOrDie(BlacklistPaths)), SM(SM) {} + : SSCL(SanitizerSpecialCaseList::createOrDie( + BlacklistPaths, SM.getFileManager().getVirtualFileSystem())), + SM(SM) {} bool SanitizerBlacklist::isBlacklistedGlobal(SanitizerMask Mask, StringRef GlobalName, diff --git a/clang/lib/Basic/SanitizerSpecialCaseList.cpp b/clang/lib/Basic/SanitizerSpecialCaseList.cpp index 5fb0f9660b15..7a820d4bef86 100644 --- a/clang/lib/Basic/SanitizerSpecialCaseList.cpp +++ b/clang/lib/Basic/SanitizerSpecialCaseList.cpp @@ -16,10 +16,11 @@ using namespace clang; std::unique_ptr SanitizerSpecialCaseList::create(const std::vector &Paths, + llvm::vfs::FileSystem &VFS, std::string &Error) { std::unique_ptr SSCL( new SanitizerSpecialCaseList()); - if (SSCL->createInternal(Paths, Error)) { + if (SSCL->createInternal(Paths, Error, VFS)) { SSCL->createSanitizerSections(); return SSCL; } @@ -27,9 +28,10 @@ SanitizerSpecialCaseList::create(const std::vector &Paths, } std::unique_ptr -SanitizerSpecialCaseList::createOrDie(const std::vector &Paths) { +SanitizerSpecialCaseList::createOrDie(const std::vector &Paths, + llvm::vfs::FileSystem &VFS) { std::string Error; - if (auto SSCL = create(Paths, Error)) + if (auto SSCL = create(Paths, VFS, Error)) return SSCL; llvm::report_fatal_error(Error); } diff --git a/clang/test/CodeGen/Inputs/sanitizer-blacklist-vfsoverlay.yaml b/clang/test/CodeGen/Inputs/sanitizer-blacklist-vfsoverlay.yaml new file mode 100644 index 000000000000..df2b22189769 --- /dev/null +++ b/clang/test/CodeGen/Inputs/sanitizer-blacklist-vfsoverlay.yaml @@ -0,0 +1,15 @@ +{ + 'version': 0, + 'roots': [ + { 'name': '@DIR@', 'type': 'directory', + 'contents': [ + { 'name': 'only-virtual-file.blacklist', 'type': 'file', + 'external-contents': '@REAL_FILE@' + }, + { 'name': 'invalid-virtual-file.blacklist', 'type': 'file', + 'external-contents': '@NONEXISTENT_FILE@' + } + ] + } + ] +} diff --git a/clang/test/CodeGen/ubsan-blacklist-vfs.c b/clang/test/CodeGen/ubsan-blacklist-vfs.c new file mode 100644 index 000000000000..0647cbf7a57b --- /dev/null +++ b/clang/test/CodeGen/ubsan-blacklist-vfs.c @@ -0,0 +1,36 @@ +// Verify ubsan doesn't emit checks for blacklisted functions and files +// RUN: echo "fun:hash" > %t-func.blacklist +// RUN: echo "src:%s" | sed -e 's/\\/\\\\/g' > %t-file.blacklist + +// RUN: rm -f %t-vfsoverlay.yaml +// RUN: rm -f %t-nonexistent.blacklist +// RUN: sed -e "s|@DIR@|%/T|g" %S/Inputs/sanitizer-blacklist-vfsoverlay.yaml | sed -e "s|@REAL_FILE@|%/t-func.blacklist|g" | sed -e "s|@NONEXISTENT_FILE@|%/t-nonexistent.blacklist|g" > %t-vfsoverlay.yaml +// RUN: %clang_cc1 -fsanitize=unsigned-integer-overflow -ivfsoverlay %t-vfsoverlay.yaml -fsanitize-blacklist=%/T/only-virtual-file.blacklist -emit-llvm %s -o - | FileCheck %s --check-prefix=FUNC + +// RUN: not %clang_cc1 -fsanitize=unsigned-integer-overflow -ivfsoverlay %t-vfsoverlay.yaml -fsanitize-blacklist=%/T/invalid-virtual-file.blacklist -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=INVALID-MAPPED-FILE +// INVALID-MAPPED-FILE: invalid-virtual-file.blacklist': {{[Nn]}}o such file or directory + +// RUN: not %clang_cc1 -fsanitize=unsigned-integer-overflow -ivfsoverlay %t-vfsoverlay.yaml -fsanitize-blacklist=%t-nonexistent.blacklist -emit-llvm %s -o - 2>&1 | FileCheck %s --check-prefix=INVALID +// INVALID: nonexistent.blacklist': {{[Nn]}}o such file or directory + +unsigned i; + +// DEFAULT: @hash +// FUNC: @hash +// FILE: @hash +unsigned hash() { +// DEFAULT: call {{.*}}void @__ubsan +// FUNC-NOT: call {{.*}}void @__ubsan +// FILE-NOT: call {{.*}}void @__ubsan + return i * 37; +} + +// DEFAULT: @add +// FUNC: @add +// FILE: @add +unsigned add() { +// DEFAULT: call {{.*}}void @__ubsan +// FUNC: call {{.*}}void @__ubsan +// FILE-NOT: call {{.*}}void @__ubsan + return i + 1; +} diff --git a/llvm/include/llvm/Support/SpecialCaseList.h b/llvm/include/llvm/Support/SpecialCaseList.h index b7400266f4df..74a7a45312aa 100644 --- a/llvm/include/llvm/Support/SpecialCaseList.h +++ b/llvm/include/llvm/Support/SpecialCaseList.h @@ -55,6 +55,7 @@ #include "llvm/ADT/StringSet.h" #include "llvm/Support/Regex.h" #include "llvm/Support/TrigramIndex.h" +#include "llvm/Support/VirtualFileSystem.h" #include #include @@ -102,8 +103,8 @@ public: protected: // Implementations of the create*() functions that can also be used by derived // classes. - bool createInternal(const std::vector &Paths, - std::string &Error); + bool createInternal(const std::vector &Paths, std::string &Error, + vfs::FileSystem &VFS = *vfs::getRealFileSystem()); bool createInternal(const MemoryBuffer *MB, std::string &Error); SpecialCaseList() = default; diff --git a/llvm/lib/Support/SpecialCaseList.cpp b/llvm/lib/Support/SpecialCaseList.cpp index 9bd1f18a4ee7..5812f075aa47 100644 --- a/llvm/lib/Support/SpecialCaseList.cpp +++ b/llvm/lib/Support/SpecialCaseList.cpp @@ -95,11 +95,11 @@ SpecialCaseList::createOrDie(const std::vector &Paths) { } bool SpecialCaseList::createInternal(const std::vector &Paths, - std::string &Error) { + std::string &Error, vfs::FileSystem &VFS) { StringMap Sections; for (const auto &Path : Paths) { ErrorOr> FileOrErr = - MemoryBuffer::getFile(Path); + VFS.getBufferForFile(Path); if (std::error_code EC = FileOrErr.getError()) { Error = (Twine("can't open file '") + Path + "': " + EC.message()).str(); return false;