diff options
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.patch | 78 |
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 |