summaryrefslogtreecommitdiff
path: root/backport-Guard-against-out-of-bounds-memory-access-when-parsing.patch
diff options
context:
space:
mode:
Diffstat (limited to 'backport-Guard-against-out-of-bounds-memory-access-when-parsing.patch')
-rw-r--r--backport-Guard-against-out-of-bounds-memory-access-when-parsing.patch78
1 files changed, 78 insertions, 0 deletions
diff --git a/backport-Guard-against-out-of-bounds-memory-access-when-parsing.patch b/backport-Guard-against-out-of-bounds-memory-access-when-parsing.patch
new file mode 100644
index 0000000..196ce7d
--- /dev/null
+++ b/backport-Guard-against-out-of-bounds-memory-access-when-parsing.patch
@@ -0,0 +1,78 @@
+From ef218fbba60bfe5b0a8ac9ea4445eac5fb0847e5 Mon Sep 17 00:00:00 2001
+From: Alex Dowad <alexinbeijing@gmail.com>
+Date: Sat, 7 Sep 2024 00:16:03 +0900
+Subject: [PATCH] Guard against out-of-bounds memory access when parsing
+ LIMIT_HEAP et al (#463)
+
+Patterns passed to pcre2_compile are not guaranteed to be
+null-terminated. Also, it can happen that there is an invalid
+pattern like this:
+
+ (*LIMIT_HEAP=123
+
+If the next byte of memory after the end of the pattern happens
+to be a digit, it will be parsed as part of the limit value. Or,
+if the next byte is a right parenthesis character, it will be taken
+as the end of the (*LIMIT_HEAP=nnn) construct.
+
+This will result in `skipatstart` being larger than `patlen`, which
+will result in underflow and an erroneous call to malloc requesting
+a huge number of bytes.
+---
+ src/pcre2_compile.c | 7 ++++---
+ testdata/testoutput15 | 4 ++--
+ 2 files changed, 6 insertions(+), 5 deletions(-)
+
+diff --git a/src/pcre2_compile.c b/src/pcre2_compile.c
+index e6843bb13..410f220b3 100644
+--- a/src/pcre2_compile.c
++++ b/src/pcre2_compile.c
+@@ -10552,12 +10552,12 @@ if ((options & PCRE2_LITERAL) == 0)
+ ptr += pp;
+ goto HAD_EARLY_ERROR;
+ }
+- while (IS_DIGIT(ptr[pp]))
++ while (pp < patlen && IS_DIGIT(ptr[pp]))
+ {
+ if (c > UINT32_MAX / 10 - 1) break; /* Integer overflow */
+ c = c*10 + (ptr[pp++] - CHAR_0);
+ }
+- if (ptr[pp++] != CHAR_RIGHT_PARENTHESIS)
++ if (pp >= patlen || ptr[pp] != CHAR_RIGHT_PARENTHESIS)
+ {
+ errorcode = ERR60;
+ ptr += pp;
+@@ -10566,7 +10566,7 @@ if ((options & PCRE2_LITERAL) == 0)
+ if (p->type == PSO_LIMH) limit_heap = c;
+ else if (p->type == PSO_LIMM) limit_match = c;
+ else limit_depth = c;
+- skipatstart += pp - skipatstart;
++ skipatstart = ++pp;
+ break;
+ }
+ break; /* Out of the table scan loop */
+@@ -10574,6 +10574,7 @@ if ((options & PCRE2_LITERAL) == 0)
+ }
+ if (i >= sizeof(pso_list)/sizeof(pso)) break; /* Out of pso loop */
+ }
++ PCRE2_ASSERT(skipatstart <= patlen);
+ }
+
+ /* End of pattern-start options; advance to start of real regex. */
+diff --git a/testdata/testoutput15 b/testdata/testoutput15
+index aa9c5c930..f36faeeaf 100644
+--- a/testdata/testoutput15
++++ b/testdata/testoutput15
+@@ -111,10 +111,10 @@ Minimum depth limit = 10
+ 3: ee
+
+ /(*LIMIT_MATCH=12bc)abc/
+-Failed: error 160 at offset 17: (*VERB) not recognized or malformed
++Failed: error 160 at offset 16: (*VERB) not recognized or malformed
+
+ /(*LIMIT_MATCH=4294967290)abc/
+-Failed: error 160 at offset 24: (*VERB) not recognized or malformed
++Failed: error 160 at offset 23: (*VERB) not recognized or malformed
+
+ /(*LIMIT_DEPTH=4294967280)abc/I
+ Capture group count = 0