[clang] [llvm] [UBSan] Implement src:*=sanitize for UBSan (PR #140529)
Qinkun Bao via cfe-commits
cfe-commits at lists.llvm.org
Tue May 20 09:02:56 PDT 2025
https://github.com/qinkunbao updated https://github.com/llvm/llvm-project/pull/140529
>From b83755d2aa0c5417ab8f359aa842449213437a7a Mon Sep 17 00:00:00 2001
From: Qinkun Bao <qinkun at google.com>
Date: Mon, 19 May 2025 11:14:01 +0000
Subject: [PATCH 1/4] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20in?=
=?UTF-8?q?itial=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.6
---
.../clang/Basic/SanitizerSpecialCaseList.h | 7 +++-
clang/lib/Basic/NoSanitizeList.cpp | 7 ++++
clang/lib/Basic/SanitizerSpecialCaseList.cpp | 16 ++++++++
.../ubsan-src-ignorelist-category.test | 37 +++++++++++++++++++
4 files changed, 66 insertions(+), 1 deletion(-)
create mode 100644 clang/test/CodeGen/ubsan-src-ignorelist-category.test
diff --git a/clang/include/clang/Basic/SanitizerSpecialCaseList.h b/clang/include/clang/Basic/SanitizerSpecialCaseList.h
index d024b7dfc2e85..25d518e7128cf 100644
--- a/clang/include/clang/Basic/SanitizerSpecialCaseList.h
+++ b/clang/include/clang/Basic/SanitizerSpecialCaseList.h
@@ -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;
diff --git a/clang/lib/Basic/NoSanitizeList.cpp b/clang/lib/Basic/NoSanitizeList.cpp
index e7e63c1f419e6..811480f914ec5 100644
--- a/clang/lib/Basic/NoSanitizeList.cpp
+++ b/clang/lib/Basic/NoSanitizeList.cpp
@@ -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);
}
diff --git a/clang/lib/Basic/SanitizerSpecialCaseList.cpp b/clang/lib/Basic/SanitizerSpecialCaseList.cpp
index 2dbf04c6ede97..7da36f3801453 100644
--- a/clang/lib/Basic/SanitizerSpecialCaseList.cpp
+++ b/clang/lib/Basic/SanitizerSpecialCaseList.cpp
@@ -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;
+}
diff --git a/clang/test/CodeGen/ubsan-src-ignorelist-category.test b/clang/test/CodeGen/ubsan-src-ignorelist-category.test
new file mode 100644
index 0000000000000..e0efd65df8652
--- /dev/null
+++ b/clang/test/CodeGen/ubsan-src-ignorelist-category.test
@@ -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;
+}
>From 51abb3b724a510dbf03e7bbc2a3af669e3784b13 Mon Sep 17 00:00:00 2001
From: Qinkun Bao <qinkun at google.com>
Date: Mon, 19 May 2025 11:21:02 +0000
Subject: [PATCH 2/4] Fix format
Created using spr 1.3.6
---
clang/lib/Basic/NoSanitizeList.cpp | 8 ++++----
clang/lib/Basic/SanitizerSpecialCaseList.cpp | 9 ++-------
2 files changed, 6 insertions(+), 11 deletions(-)
diff --git a/clang/lib/Basic/NoSanitizeList.cpp b/clang/lib/Basic/NoSanitizeList.cpp
index 811480f914ec5..671afc14de04d 100644
--- a/clang/lib/Basic/NoSanitizeList.cpp
+++ b/clang/lib/Basic/NoSanitizeList.cpp
@@ -44,12 +44,12 @@ 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");
+ 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;
+ if (NoSanLine > 0 && SanLine > 0) {
+ return NoSanLine > SanLine;
}
return SSCL->inSection(Mask, "src", FileName, Category);
}
diff --git a/clang/lib/Basic/SanitizerSpecialCaseList.cpp b/clang/lib/Basic/SanitizerSpecialCaseList.cpp
index 7da36f3801453..5030a7740fc0a 100644
--- a/clang/lib/Basic/SanitizerSpecialCaseList.cpp
+++ b/clang/lib/Basic/SanitizerSpecialCaseList.cpp
@@ -56,16 +56,11 @@ void SanitizerSpecialCaseList::createSanitizerSections() {
bool SanitizerSpecialCaseList::inSection(SanitizerMask Mask, StringRef Prefix,
StringRef Query,
StringRef Category) const {
- for (auto &S : SanitizerSections)
- if ((S.Mask & Mask) &&
- SpecialCaseList::inSectionBlame(S.Entries, Prefix, Query, Category))
- return true;
-
- return false;
+ return inSectionBlame(Mask, Prefix, Query, Category) > 0;
}
unsigned SanitizerSpecialCaseList::inSectionBlame(SanitizerMask Mask,
- StringRef Prefix,
+ sp StringRef Prefix,
StringRef Query,
StringRef Category) const {
for (auto &S : SanitizerSections) {
>From df61d7a68cd4bfe730d8efcdc01dd697e876c17b Mon Sep 17 00:00:00 2001
From: Qinkun Bao <qinkun at google.com>
Date: Mon, 19 May 2025 13:16:38 +0000
Subject: [PATCH 3/4] Fix format
Created using spr 1.3.6
---
clang/lib/Basic/SanitizerSpecialCaseList.cpp | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/clang/lib/Basic/SanitizerSpecialCaseList.cpp b/clang/lib/Basic/SanitizerSpecialCaseList.cpp
index 5030a7740fc0a..3bf79876235db 100644
--- a/clang/lib/Basic/SanitizerSpecialCaseList.cpp
+++ b/clang/lib/Basic/SanitizerSpecialCaseList.cpp
@@ -60,7 +60,7 @@ bool SanitizerSpecialCaseList::inSection(SanitizerMask Mask, StringRef Prefix,
}
unsigned SanitizerSpecialCaseList::inSectionBlame(SanitizerMask Mask,
- sp StringRef Prefix,
+ StringRef Prefix,
StringRef Query,
StringRef Category) const {
for (auto &S : SanitizerSections) {
>From af1c6c8131e15cd10768a293c0d31ac5fd0b1e0d Mon Sep 17 00:00:00 2001
From: Qinkun Bao <qinkun at google.com>
Date: Tue, 20 May 2025 12:02:47 -0400
Subject: [PATCH 4/4] Update SpecialCaseList.cpp
---
llvm/lib/Support/SpecialCaseList.cpp | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/llvm/lib/Support/SpecialCaseList.cpp b/llvm/lib/Support/SpecialCaseList.cpp
index dddf84cbb1ced..5145cccc91e3b 100644
--- a/llvm/lib/Support/SpecialCaseList.cpp
+++ b/llvm/lib/Support/SpecialCaseList.cpp
@@ -63,6 +63,11 @@ Error SpecialCaseList::Matcher::insert(StringRef Pattern, unsigned LineNumber,
.moveInto(Pair.first))
return Err;
Pair.second = LineNumber;
+ } else {
+ // We should update the new line number if an entry with the same pattern
+ // repeats.
+ auto &Pair = It->getValue();
+ Pair.second = LineNumber;
}
return Error::success();
}
More information about the cfe-commits
mailing list