-
Notifications
You must be signed in to change notification settings - Fork 11.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Support] Fix buffer overflow in regcomp #76681
base: main
Are you sure you want to change the base?
Conversation
`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@adalogics.com>
@llvm/pr-subscribers-llvm-support Author: None (DavidKorczynski) Changes
Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=65423 Full diff: https://github.com/llvm/llvm-project/pull/76681.diff 1 Files Affected:
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 &&
|
You can test this locally with the following command:git-clang-format --diff 463dad107f4cb60ae1d49138143d6797599fb1fb 9ec1407e3f3fc4ab7518b2b7c28869bd870705f9 -- llvm/lib/Support/regcomp.c llvm/unittests/Support/SpecialCaseListTest.cpp View the diff from clang-format here.diff --git a/llvm/lib/Support/regcomp.c b/llvm/lib/Support/regcomp.c
index 1f68008d6a..08ef1adcc5 100644
--- a/llvm/lib/Support/regcomp.c
+++ b/llvm/lib/Support/regcomp.c
@@ -1601,9 +1601,9 @@ findmust(struct parse *p, struct re_guts *g)
sop s;
char *cp;
sopno i;
- unsigned int skipsize;
+ unsigned int skipsize;
- /* avoid making error situations worse */
+ /* avoid making error situations worse */
if (p->error != 0)
return;
@@ -1626,17 +1626,17 @@ findmust(struct parse *p, struct re_guts *g)
case OCH_:
scan--;
do {
- /* Ensure end is not skipped */
- skipsize = OPND(s);
- while (skipsize > 0) {
- if (OP(*scan) == OEND) {
- g->iflags |= REGEX_BAD;
- return;
- }
- scan++;
- skipsize--;
- }
- s = *scan;
+ /* 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 &&
OP(s) != OOR2) {
|
I'm not entirely sure about what to do with the formatting -- the current PR uses tabs as the rest of What to do? |
No worries about the formatting - sticking with the formatting of the rest of the file is fine. Does this need test coverage? Is there any chance this bug is fixed in the upstream/original regex library this code is based on? Be nice to be able to just take their fix rather than coming up with our own if possible. |
What's the regex that causes this issue? I'm not sure this fix is correct -- I don't think we should be emitting an |
This is the stacktrace:
In this sense it seems the pattern is defined here: In ASCII, the input from the fuzzer looks as follows:
|
Signed-off-by: David Korczynski <david@adalogics.com>
I'm not strongly opinionated on this: OSS-Fuzz will catch and flag the bug if a regression happens, but having a test will make it more obvious, and instantaneous, if a regression happens. Added a test. |
OQUEST_
andOCH_
causes the scan pointer to skip elements ing
'sstrip
buffer. However, the terminating character ofg->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