[llvm] [Support] Fix buffer overflow in regcomp (PR #76681)

via llvm-commits llvm-commits at lists.llvm.org
Fri Jan 5 09:01:37 PST 2024


https://github.com/DavidKorczynski updated https://github.com/llvm/llvm-project/pull/76681

>From 22fcd1ef7e9a79a861313bc0f2d4c84767e2a0e8 Mon Sep 17 00:00:00 2001
From: David Korczynski <david at adalogics.com>
Date: Mon, 1 Jan 2024 07:16:36 -0800
Subject: [PATCH 1/2] [Support] Fix buffer overflow in regcomp

`OQUEST_` and `OCH_` causes the scan pointer to skip elements in `g`'s
`strip` buffer. However, the terminating character of `g->strip` may be
within the skipped elements, and there is currently no checking of that.
This adds a check on the skipped elements to ensure no overflow happens.

Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65423

Signed-off-by: David Korczynski <david at adalogics.com>
---
 llvm/lib/Support/regcomp.c | 12 +++++++++++-
 1 file changed, 11 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Support/regcomp.c b/llvm/lib/Support/regcomp.c
index 990aef32a396fa..1f68008d6a2937 100644
--- a/llvm/lib/Support/regcomp.c
+++ b/llvm/lib/Support/regcomp.c
@@ -1601,6 +1601,7 @@ findmust(struct parse *p, struct re_guts *g)
 	sop s;
 	char *cp;
 	sopno i;
+	unsigned int skipsize;
 
 	/* avoid making error situations worse */
 	if (p->error != 0)
@@ -1625,7 +1626,16 @@ findmust(struct parse *p, struct re_guts *g)
 		case OCH_:
 			scan--;
 			do {
-				scan += OPND(s);
+				/* Ensure end is not skipped */
+				skipsize = OPND(s);
+				while (skipsize > 0) {
+					if (OP(*scan) == OEND) {
+						g->iflags |= REGEX_BAD;
+						return;
+					}
+					scan++;
+					skipsize--;
+				}
 				s = *scan;
 				/* assert() interferes w debug printouts */
 				if (OP(s) != O_QUEST && OP(s) != O_CH &&

>From 9ec1407e3f3fc4ab7518b2b7c28869bd870705f9 Mon Sep 17 00:00:00 2001
From: David Korczynski <david at adalogics.com>
Date: Fri, 5 Jan 2024 09:00:52 -0800
Subject: [PATCH 2/2] [SpecialCaseListTest] add OSS-Fuzz regression

Signed-off-by: David Korczynski <david at adalogics.com>
---
 llvm/unittests/Support/SpecialCaseListTest.cpp | 15 +++++++++++++++
 1 file changed, 15 insertions(+)

diff --git a/llvm/unittests/Support/SpecialCaseListTest.cpp b/llvm/unittests/Support/SpecialCaseListTest.cpp
index 4289a5e7021556..8ca59955c7aab1 100644
--- a/llvm/unittests/Support/SpecialCaseListTest.cpp
+++ b/llvm/unittests/Support/SpecialCaseListTest.cpp
@@ -306,4 +306,19 @@ TEST_F(SpecialCaseListTest, Version2) {
   EXPECT_TRUE(SCL->inSection("sect2", "fun", "bar"));
   EXPECT_FALSE(SCL->inSection("sect3", "fun", "bar"));
 }
+
+TEST_F(SpecialCaseListTest, OSSFuzz65423) {
+  // Regression test for:
+  // https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65423
+  const uint8_t Data[38] = {0x23, 0x21, 0x73, 0x70, 0x65, 0x63, 0x69, 0x61,
+                            0x6c, 0x2d, 0x63, 0x61, 0x73, 0x65, 0x2d, 0x6c,
+                            0x69, 0x73, 0x74, 0x2d, 0x76, 0x31, 0x0a, 0x3a,
+                            0x29, 0x7b, 0x30, 0x7d, 0x28, 0x20, 0x20, 0x20,
+                            0x7c, 0x20, 0x29, 0x28, 0x5c, 0x31};
+  std::string Payload(reinterpret_cast<const char *>(Data), 38);
+  std::unique_ptr<llvm::MemoryBuffer> Buf =
+      llvm::MemoryBuffer::getMemBuffer(Payload);
+  std::string Error;
+  SpecialCaseList::create(Buf.get(), Error);
+}
 }



More information about the llvm-commits mailing list