Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion clang/include/clang/Basic/SanitizerSpecialCaseList.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,18 @@ class SanitizerSpecialCaseList : public llvm::SpecialCaseList {
bool inSection(SanitizerMask Mask, StringRef Prefix, StringRef Query,
StringRef Category = StringRef()) const;

// Query ignorelisted entries if any bit in Mask matches the entry's section.
// Return 0 if not found. If found, return the line number (starts with 1).
unsigned inSectionBlame(SanitizerMask Mask, StringRef Prefix, StringRef Query,
StringRef Category = StringRef()) const;

protected:
// Initialize SanitizerSections.
void createSanitizerSections();

struct SanitizerSection {
SanitizerSection(SanitizerMask SM, SectionEntries &E)
: Mask(SM), Entries(E){};
: Mask(SM), Entries(E) {};

SanitizerMask Mask;
SectionEntries &Entries;
Expand Down
7 changes: 7 additions & 0 deletions clang/lib/Basic/NoSanitizeList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,13 @@ bool NoSanitizeList::containsFunction(SanitizerMask Mask,

bool NoSanitizeList::containsFile(SanitizerMask Mask, StringRef FileName,
StringRef Category) const {
unsigned nosanline = SSCL->inSectionBlame(Mask, "src", FileName, Category);
unsigned sanline = SSCL->inSectionBlame(Mask, "src", FileName, "sanitize");
// If we have two cases such as `src:a.cpp=sanitize` and `src:a.cpp`, the
// current entry override the previous entry.
if (nosanline > 0 && sanline > 0) {
return nosanline > sanline;
}
return SSCL->inSection(Mask, "src", FileName, Category);
}

Expand Down
16 changes: 16 additions & 0 deletions clang/lib/Basic/SanitizerSpecialCaseList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,19 @@ bool SanitizerSpecialCaseList::inSection(SanitizerMask Mask, StringRef Prefix,

return false;
}

unsigned SanitizerSpecialCaseList::inSectionBlame(SanitizerMask Mask,
StringRef Prefix,
StringRef Query,
StringRef Category) const {
for (auto &S : SanitizerSections) {
if (S.Mask & Mask) {
unsigned lineNum =
SpecialCaseList::inSectionBlame(S.Entries, Prefix, Query, Category);
if (lineNum > 0) {
return lineNum;
}
}
}
return 0;
}
37 changes: 37 additions & 0 deletions clang/test/CodeGen/ubsan-src-ignorelist-category.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// RUN: rm -rf %t
// RUN: split-file %s %t
// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsanitize=signed-integer-overflow -fsanitize-ignorelist=%t/src.ignorelist -emit-llvm %t/test1.c -o - | FileCheck %s -check-prefix=CHECK-ALLOWLIST
// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsanitize=signed-integer-overflow -fsanitize-ignorelist=%t/src.ignorelist -emit-llvm %t/test2.c -o - | FileCheck %s -check-prefix=CHECK-IGNORELIST
// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsanitize=signed-integer-overflow -fsanitize-ignorelist=%t/src.ignorelist.contradict1 -emit-llvm %t/test1.c -o - | FileCheck %s -check-prefix=CHECK-ALLOWLISTOVERIDE1
// RUN: %clang_cc1 -triple x86_64-linux-gnu -fsanitize=signed-integer-overflow -fsanitize-ignorelist=%t/src.ignorelist.contradict2 -emit-llvm %t/test1.c -o - | FileCheck %s -check-prefix=CHECK-ALLOWLISTOVERIDE2


// Verify ubsan only emits checks for files in the allowlist

//--- src.ignorelist
src:*
src:*/test1.c=sanitize

//--- src.ignorelist.contradict1
src:*
src:*/test1.c=sanitize
src:*/test1.c

//--- src.ignorelist.contradict2
src:*
src:*/test1.c
src:*/test1.c=sanitize

//--- test1.c
int add1(int a, int b) {
// CHECK-ALLOWLIST: llvm.sadd.with.overflow.i32
// CHECK-ALLOWLISTOVERIDE1-NOT: llvm.sadd.with.overflow.i32
// CHECK-ALLOWLISTOVERIDE2: llvm.sadd.with.overflow.i32
return a+b;
}

//--- test2.c
int add2(int a, int b) {
// CHECK-IGNORELIST-NOT: llvm.sadd.with.overflow.i32
return a+b;
}
18 changes: 12 additions & 6 deletions llvm/lib/Support/SpecialCaseList.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -132,18 +132,24 @@ bool SpecialCaseList::createInternal(const MemoryBuffer *MB,
Expected<SpecialCaseList::Section *>
SpecialCaseList::addSection(StringRef SectionStr, unsigned LineNo,
bool UseGlobs) {
Sections.emplace_back();
auto &Section = Sections.back();
Section.SectionStr = SectionStr;

if (auto Err = Section.SectionMatcher->insert(SectionStr, LineNo, UseGlobs)) {
auto it =
std::find_if(Sections.begin(), Sections.end(), [&](const Section &s) {
return s.SectionStr == SectionStr;
});
if (it == Sections.end()) {
Sections.emplace_back();
auto &sec = Sections.back();
sec.SectionStr = SectionStr;
}
it = std::prev(Sections.end());
if (auto Err = it->SectionMatcher->insert(SectionStr, LineNo, UseGlobs)) {
return createStringError(errc::invalid_argument,
"malformed section at line " + Twine(LineNo) +
": '" + SectionStr +
"': " + toString(std::move(Err)));
}

return &Section;
return &(*it);
}

bool SpecialCaseList::parse(const MemoryBuffer *MB, std::string &Error) {
Expand Down
19 changes: 19 additions & 0 deletions llvm/unittests/Support/SpecialCaseListTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,4 +306,23 @@ TEST_F(SpecialCaseListTest, Version2) {
EXPECT_TRUE(SCL->inSection("sect2", "fun", "bar"));
EXPECT_FALSE(SCL->inSection("sect3", "fun", "bar"));
}

TEST_F(SpecialCaseListTest, Version3) {
std::unique_ptr<SpecialCaseList> SCL = makeSpecialCaseList("[sect1]\n"
"fun:foo*\n"
"[sect1]\n"
"fun:bar*\n"
"[sect2]\n"
"fun:def\n");
EXPECT_TRUE(SCL->inSection("sect1", "fun", "fooz"));
EXPECT_TRUE(SCL->inSection("sect1", "fun", "barz"));
EXPECT_FALSE(SCL->inSection("sect2", "fun", "fooz"));

EXPECT_TRUE(SCL->inSection("sect2", "fun", "def"));
EXPECT_FALSE(SCL->inSection("sect1", "fun", "def"));

EXPECT_EQ(2u, SCL->inSectionBlame("sect1", "fun", "fooz"));
EXPECT_EQ(4u, SCL->inSectionBlame("sect1", "fun", "barz"));
EXPECT_EQ(6u, SCL->inSectionBlame("sect2", "fun", "def"));
}
}
Loading