summaryrefslogtreecommitdiff
path: root/backport-pcre2_compile-avoid-1-byte-buffer-overread-parsing-V.patch
diff options
context:
space:
mode:
Diffstat (limited to 'backport-pcre2_compile-avoid-1-byte-buffer-overread-parsing-V.patch')
-rw-r--r--backport-pcre2_compile-avoid-1-byte-buffer-overread-parsing-V.patch118
1 files changed, 118 insertions, 0 deletions
diff --git a/backport-pcre2_compile-avoid-1-byte-buffer-overread-parsing-V.patch b/backport-pcre2_compile-avoid-1-byte-buffer-overread-parsing-V.patch
new file mode 100644
index 0000000..8d349cc
--- /dev/null
+++ b/backport-pcre2_compile-avoid-1-byte-buffer-overread-parsing-V.patch
@@ -0,0 +1,118 @@
+From bc367f1880ae5ccc771d5780e35df4c42744a9c4 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Carlo=20Marcelo=20Arenas=20Bel=C3=B3n?= <carenas@gmail.com>
+Date: Sun, 22 Sep 2024 01:49:03 -0700
+Subject: [PATCH] pcre2_compile: avoid 1 byte buffer overread parsing VERBs
+ (#487)
+
+As reported recently by ef218fb (Guard against out-of-bounds memory
+access when parsing LIMIT_HEAP et al (#463), 2024-09-07), a malformed
+pattern could result in reading 1 byte past its end.
+
+Fix a similar issue that affects all VERBs and add test cases to
+ensure the original bug and all its siblings are no longer an issue.
+
+While at it fix the wording of the related documentation.
+---
+ doc/pcre2syntax.3 | 4 ++--
+ src/pcre2_compile.c | 11 +++--------
+ testdata/testinput2 | 8 ++++++++
+ testdata/testoutput2 | 12 ++++++++++++
+ 4 files changed, 25 insertions(+), 10 deletions(-)
+
+diff --git a/doc/pcre2syntax.3 b/doc/pcre2syntax.3
+index 232125b82..db0bb6586 100644
+--- a/doc/pcre2syntax.3
++++ b/doc/pcre2syntax.3
+@@ -408,8 +408,8 @@ only one hyphen. Setting (but no unsetting) is allowed after (?^ for example
+ example (?i:...).
+ .P
+ The following are recognized only at the very start of a pattern or after one
+-of the newline or \eR options with similar syntax. More than one of them may
+-appear. For the first three, d is a decimal number.
++of the newline or \eR sequences or options with similar syntax. More than one
++of them may appear. For the first three, d is a decimal number.
+ .sp
+ (*LIMIT_DEPTH=d) set the backtracking limit to d
+ (*LIMIT_HEAP=d) set the heap size limit to d * 1024 bytes
+diff --git a/src/pcre2_compile.c b/src/pcre2_compile.c
+index 7e48b26..3d9a500 100644
+--- a/src/pcre2_compile.c
++++ b/src/pcre2_compile.c
+@@ -9877,13 +9877,14 @@ if ((options & PCRE2_LITERAL) == 0)
+ {
+ for (i = 0; i < sizeof(pso_list)/sizeof(pso); i++)
+ {
+- uint32_t c, pp;
+ const pso *p = pso_list + i;
+
+ if (patlen - skipatstart - 2 >= p->length &&
+ PRIV(strncmp_c8)(ptr + skipatstart + 2, (char *)(p->name),
+ p->length) == 0)
+ {
++ uint32_t c, pp;
++
+ skipatstart += p->length + 2;
+ switch(p->type)
+ {
+@@ -9910,18 +9911,12 @@ if ((options & PCRE2_LITERAL) == 0)
+ case PSO_LIMH:
+ c = 0;
+ pp = skipatstart;
+- if (!IS_DIGIT(ptr[pp]))
+- {
+- errorcode = ERR60;
+- ptr += pp;
+- goto HAD_EARLY_ERROR;
+- }
+ while (pp < patlen && IS_DIGIT(ptr[pp]))
+ {
+ if (c > UINT32_MAX / 10 - 1) break; /* Integer overflow */
+ c = c*10 + (ptr[pp++] - CHAR_0);
+ }
+- if (pp >= patlen || ptr[pp] != CHAR_RIGHT_PARENTHESIS)
++ if (pp >= patlen || pp == skipatstart || ptr[pp] != CHAR_RIGHT_PARENTHESIS)
+ {
+ errorcode = ERR60;
+ ptr += pp;
+diff --git a/testdata/testinput2 b/testdata/testinput2
+index a869c5bc2..542d14520 100644
+--- a/testdata/testinput2
++++ b/testdata/testinput2
+@@ -5261,6 +5261,14 @@ a)"xI
+
+ /(*LIMIT_HEAP=0)xxx/I
+
++/(*LIMIT_HEAP=123/use_length
++
++/(*LIMIT_MATCH=/use_length
++
++/(*CRLF)(*LIMIT_DEPTH=/use_length
++
++/(*CRLF)(*LIMIT_RECURSION=1)(*BOGUS/use_length
++
+ /\d{0,3}(*:abc)(?C1)xxx/callout_info
+
+ # ----------------------------------------------------------------------
+diff --git a/testdata/testoutput2 b/testdata/testoutput2
+index bf7b7620e..b99d64781 100644
+--- a/testdata/testoutput2
++++ b/testdata/testoutput2
+@@ -16220,6 +16220,18 @@ First code unit = 'x'
+ Last code unit = 'x'
+ Subject length lower bound = 3
+
++/(*LIMIT_HEAP=123/use_length
++Failed: error 160 at offset 16: (*VERB) not recognized or malformed
++
++/(*LIMIT_MATCH=/use_length
++Failed: error 160 at offset 14: (*VERB) not recognized or malformed
++
++/(*CRLF)(*LIMIT_DEPTH=/use_length
++Failed: error 160 at offset 21: (*VERB) not recognized or malformed
++
++/(*CRLF)(*LIMIT_RECURSION=1)(*BOGUS/use_length
++Failed: error 160 at offset 34: (*VERB) not recognized or malformed
++
+ /\d{0,3}(*:abc)(?C1)xxx/callout_info
+ Callout 1 x
+