From b62425e3e36c10acb2e99a9db5e5b73ed2a1e8fd Mon Sep 17 00:00:00 2001 From: Michael Tremer Date: Mon, 17 Aug 2015 23:33:31 +0100 Subject: [PATCH] pcre: Fix more buffer overflows Signed-off-by: Michael Tremer --- config/rootfiles/core/94/filelists/pcre | 1 + lfs/pcre | 3 + ...cre-8.37-Fix-another-buffer-overflow.patch | 110 ++++++++++ ...low-for-named-references-in-situatio.patch | 190 ++++++++++++++++++ ...d-reference-to-duplicate-group-numbe.patch | 98 +++++++++ 5 files changed, 402 insertions(+) create mode 120000 config/rootfiles/core/94/filelists/pcre create mode 100644 src/patches/pcre-8.37-Fix-another-buffer-overflow.patch create mode 100644 src/patches/pcre-8.37-Fix-buffer-overflow-for-named-references-in-situatio.patch create mode 100644 src/patches/pcre-8.37-Fix-named-forward-reference-to-duplicate-group-numbe.patch diff --git a/config/rootfiles/core/94/filelists/pcre b/config/rootfiles/core/94/filelists/pcre new file mode 120000 index 0000000000..b390d9a367 --- /dev/null +++ b/config/rootfiles/core/94/filelists/pcre @@ -0,0 +1 @@ +../../../common/pcre \ No newline at end of file diff --git a/lfs/pcre b/lfs/pcre index 8f207da7ba..f9e63c67a2 100644 --- a/lfs/pcre +++ b/lfs/pcre @@ -72,6 +72,9 @@ $(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar axf $(DIR_DL)/$(DL_FILE) cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/pcre-8.37-Fix-buffer-overflow-for-named-recursive-back-referen.patch cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/pcre-8.37-Fix-buffer-overflow-for-forward-reference-within-bac.patch + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/pcre-8.37-Fix-another-buffer-overflow.patch + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/pcre-8.37-Fix-buffer-overflow-for-named-references-in-situatio.patch + cd $(DIR_APP) && patch -Np1 < $(DIR_SRC)/src/patches/pcre-8.37-Fix-named-forward-reference-to-duplicate-group-numbe.patch cd $(DIR_APP) && ./configure \ --prefix=/usr \ --disable-static \ diff --git a/src/patches/pcre-8.37-Fix-another-buffer-overflow.patch b/src/patches/pcre-8.37-Fix-another-buffer-overflow.patch new file mode 100644 index 0000000000..20ead09231 --- /dev/null +++ b/src/patches/pcre-8.37-Fix-another-buffer-overflow.patch @@ -0,0 +1,110 @@ +From f6efcf125123199d446c5561266c3c3846ed9f30 Mon Sep 17 00:00:00 2001 +From: ph10 +Date: Wed, 3 Jun 2015 16:51:59 +0000 +Subject: [PATCH] Fix another buffer overflow. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Ported to 8.37: + +commit 225f0d5eb16c7a26591a1e3f286c7476907b5a6a +Author: ph10 +Date: Wed Jun 3 16:51:59 2015 +0000 + + Fix another buffer overflow. + + git-svn-id: svn://vcs.exim.org/pcre/code/trunk@1562 2f5784b3-3f2a-0410-8824-cb99058d5e15 + +Signed-off-by: Petr Písař +--- + pcre_compile.c | 7 ++++++- + testdata/testinput2 | 2 ++ + testdata/testoutput11-16 | 2 +- + testdata/testoutput11-32 | 2 +- + testdata/testoutput11-8 | 2 +- + testdata/testoutput2 | 2 ++ + 6 files changed, 13 insertions(+), 4 deletions(-) + +diff --git a/pcre_compile.c b/pcre_compile.c +index 8b4aaef..f5d2384 100644 +--- a/pcre_compile.c ++++ b/pcre_compile.c +@@ -7210,7 +7210,12 @@ for (;; ptr++) + real compile this will be picked up and the reference wrapped with + OP_ONCE to make it atomic, so we must space in case this occurs. */ + +- if (recno == 0) *lengthptr += 2 + 2*LINK_SIZE; ++ /* In fact, this can happen for a non-forward reference because ++ another group with the same number might be created later. This ++ issue is fixed "properly" in PCRE2. As PCRE1 is now in maintenance ++ only mode, we finesse the bug by allowing more memory always. */ ++ ++ /* if (recno == 0) */ *lengthptr += 2 + 2*LINK_SIZE; + } + + /* In the real compile, search the name table. We check the name +diff --git a/testdata/testinput2 b/testdata/testinput2 +index 5cc9ce6..e12de3a 100644 +--- a/testdata/testinput2 ++++ b/testdata/testinput2 +@@ -4156,4 +4156,6 @@ backtracking verbs. --/ + + /(?=di(?<=(?1))|(?=(.))))/ + ++"(?J:(?|(?'R')(\k'R')|((?'R'))))" ++ + /-- End of testinput2 --/ +diff --git a/testdata/testoutput11-16 b/testdata/testoutput11-16 +index 422f2ad..e222e7c 100644 +--- a/testdata/testoutput11-16 ++++ b/testdata/testoutput11-16 +@@ -231,7 +231,7 @@ Memory allocation (code space): 73 + ------------------------------------------------------------------ + + /(?Pa)...(?P=a)bbb(?P>a)d/BM +-Memory allocation (code space): 61 ++Memory allocation (code space): 77 + ------------------------------------------------------------------ + 0 24 Bra + 2 5 CBra 1 +diff --git a/testdata/testoutput11-32 b/testdata/testoutput11-32 +index d953ec8..9a80ec9 100644 +--- a/testdata/testoutput11-32 ++++ b/testdata/testoutput11-32 +@@ -231,7 +231,7 @@ Memory allocation (code space): 155 + ------------------------------------------------------------------ + + /(?Pa)...(?P=a)bbb(?P>a)d/BM +-Memory allocation (code space): 125 ++Memory allocation (code space): 157 + ------------------------------------------------------------------ + 0 24 Bra + 2 5 CBra 1 +diff --git a/testdata/testoutput11-8 b/testdata/testoutput11-8 +index 6ec18ec..3adaca2 100644 +--- a/testdata/testoutput11-8 ++++ b/testdata/testoutput11-8 +@@ -231,7 +231,7 @@ Memory allocation (code space): 45 + ------------------------------------------------------------------ + + /(?Pa)...(?P=a)bbb(?P>a)d/BM +-Memory allocation (code space): 38 ++Memory allocation (code space): 50 + ------------------------------------------------------------------ + 0 30 Bra + 3 7 CBra 1 +diff --git a/testdata/testoutput2 b/testdata/testoutput2 +index 4decb8d..5bad26c 100644 +--- a/testdata/testoutput2 ++++ b/testdata/testoutput2 +@@ -14428,4 +14428,6 @@ Failed: lookbehind assertion is not fixed length at offset 17 + /(?=di(?<=(?1))|(?=(.))))/ + Failed: unmatched parentheses at offset 23 + ++"(?J:(?|(?'R')(\k'R')|((?'R'))))" ++ + /-- End of testinput2 --/ +-- +2.4.3 + diff --git a/src/patches/pcre-8.37-Fix-buffer-overflow-for-named-references-in-situatio.patch b/src/patches/pcre-8.37-Fix-buffer-overflow-for-named-references-in-situatio.patch new file mode 100644 index 0000000000..ab1b96213a --- /dev/null +++ b/src/patches/pcre-8.37-Fix-buffer-overflow-for-named-references-in-situatio.patch @@ -0,0 +1,190 @@ +From b3f0b0dd971314df8f865e221aa1a88e75d6d1a6 Mon Sep 17 00:00:00 2001 +From: ph10 +Date: Wed, 5 Aug 2015 15:38:32 +0000 +Subject: [PATCH] Fix buffer overflow for named references in (?| situations. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Ported for 8.37: + +commit 7af8e8717def179fd7b69e173abd347c1a3547cb +Author: ph10 +Date: Wed Aug 5 15:38:32 2015 +0000 + + Fix buffer overflow for named references in (?| situations. + + git-svn-id: svn://vcs.exim.org/pcre/code/trunk@1585 2f5784b3-3f2a-0410-8824-cb99058d5e15 + +Signed-off-by: Petr Písař +--- + pcre_compile.c | 74 ++++++++++++++++++++++++++++++---------------------- + pcre_internal.h | 1 + + testdata/testinput2 | 2 ++ + testdata/testoutput2 | 2 ++ + 4 files changed, 48 insertions(+), 31 deletions(-) + +diff --git a/pcre_compile.c b/pcre_compile.c +index f5d2384..5fe5c1d 100644 +--- a/pcre_compile.c ++++ b/pcre_compile.c +@@ -6641,6 +6641,7 @@ for (;; ptr++) + /* ------------------------------------------------------------ */ + case CHAR_VERTICAL_LINE: /* Reset capture count for each branch */ + reset_bracount = TRUE; ++ cd->dupgroups = TRUE; /* Record (?| encountered */ + /* Fall through */ + + /* ------------------------------------------------------------ */ +@@ -7151,7 +7152,8 @@ for (;; ptr++) + if (lengthptr != NULL) + { + named_group *ng; +- ++ recno = 0; ++ + if (namelen == 0) + { + *errorcodeptr = ERR62; +@@ -7168,32 +7170,6 @@ for (;; ptr++) + goto FAILED; + } + +- /* The name table does not exist in the first pass; instead we must +- scan the list of names encountered so far in order to get the +- number. If the name is not found, set the value to 0 for a forward +- reference. */ +- +- recno = 0; +- ng = cd->named_groups; +- for (i = 0; i < cd->names_found; i++, ng++) +- { +- if (namelen == ng->length && +- STRNCMP_UC_UC(name, ng->name, namelen) == 0) +- { +- open_capitem *oc; +- recno = ng->number; +- if (is_recurse) break; +- for (oc = cd->open_caps; oc != NULL; oc = oc->next) +- { +- if (oc->number == recno) +- { +- oc->flag = TRUE; +- break; +- } +- } +- } +- } +- + /* Count named back references. */ + + if (!is_recurse) cd->namedrefcount++; +@@ -7215,7 +7191,44 @@ for (;; ptr++) + issue is fixed "properly" in PCRE2. As PCRE1 is now in maintenance + only mode, we finesse the bug by allowing more memory always. */ + +- /* if (recno == 0) */ *lengthptr += 2 + 2*LINK_SIZE; ++ *lengthptr += 2 + 2*LINK_SIZE; ++ ++ /* It is even worse than that. The current reference may be to an ++ existing named group with a different number (so apparently not ++ recursive) but which later on is also attached to a group with the ++ current number. This can only happen if $(| has been previous ++ encountered. In that case, we allow yet more memory, just in case. ++ (Again, this is fixed "properly" in PCRE2. */ ++ ++ if (cd->dupgroups) *lengthptr += 2 + 2*LINK_SIZE; ++ ++ /* Otherwise, check for recursion here. The name table does not exist ++ in the first pass; instead we must scan the list of names encountered ++ so far in order to get the number. If the name is not found, leave ++ the value of recno as 0 for a forward reference. */ ++ ++ else ++ { ++ ng = cd->named_groups; ++ for (i = 0; i < cd->names_found; i++, ng++) ++ { ++ if (namelen == ng->length && ++ STRNCMP_UC_UC(name, ng->name, namelen) == 0) ++ { ++ open_capitem *oc; ++ recno = ng->number; ++ if (is_recurse) break; ++ for (oc = cd->open_caps; oc != NULL; oc = oc->next) ++ { ++ if (oc->number == recno) ++ { ++ oc->flag = TRUE; ++ break; ++ } ++ } ++ } ++ } ++ } + } + + /* In the real compile, search the name table. We check the name +@@ -7262,8 +7275,6 @@ for (;; ptr++) + for (i++; i < cd->names_found; i++) + { + if (STRCMP_UC_UC(slot + IMM2_SIZE, cslot + IMM2_SIZE) != 0) break; +- +- + count++; + cslot += cd->name_entry_size; + } +@@ -9189,6 +9200,7 @@ cd->names_found = 0; + cd->name_entry_size = 0; + cd->name_table = NULL; + cd->dupnames = FALSE; ++cd->dupgroups = FALSE; + cd->namedrefcount = 0; + cd->start_code = cworkspace; + cd->hwm = cworkspace; +@@ -9223,7 +9235,7 @@ if (errorcode != 0) goto PCRE_EARLY_ERROR_RETURN; + + DPRINTF(("end pre-compile: length=%d workspace=%d\n", length, + (int)(cd->hwm - cworkspace))); +- ++ + if (length > MAX_PATTERN_SIZE) + { + errorcode = ERR20; +diff --git a/pcre_internal.h b/pcre_internal.h +index dd0ac7f..7ca6020 100644 +--- a/pcre_internal.h ++++ b/pcre_internal.h +@@ -2446,6 +2446,7 @@ typedef struct compile_data { + BOOL had_pruneorskip; /* (*PRUNE) or (*SKIP) encountered */ + BOOL check_lookbehind; /* Lookbehinds need later checking */ + BOOL dupnames; /* Duplicate names exist */ ++ BOOL dupgroups; /* Duplicate groups exist: (?| found */ + BOOL iscondassert; /* Next assert is a condition */ + int nltype; /* Newline type */ + int nllen; /* Newline string length */ +diff --git a/testdata/testinput2 b/testdata/testinput2 +index e12de3a..8e044f8 100644 +--- a/testdata/testinput2 ++++ b/testdata/testinput2 +@@ -4158,4 +4158,6 @@ backtracking verbs. --/ + + "(?J:(?|(?'R')(\k'R')|((?'R'))))" + ++/(?J:(?|(:(?|(?'R')(\k'R')|((?'R')))H'Rk'Rf)|s(?'R')))/ ++ + /-- End of testinput2 --/ +diff --git a/testdata/testoutput2 b/testdata/testoutput2 +index 5bad26c..6019425 100644 +--- a/testdata/testoutput2 ++++ b/testdata/testoutput2 +@@ -14430,4 +14430,6 @@ Failed: unmatched parentheses at offset 23 + + "(?J:(?|(?'R')(\k'R')|((?'R'))))" + ++/(?J:(?|(:(?|(?'R')(\k'R')|((?'R')))H'Rk'Rf)|s(?'R')))/ ++ + /-- End of testinput2 --/ +-- +2.4.3 + diff --git a/src/patches/pcre-8.37-Fix-named-forward-reference-to-duplicate-group-numbe.patch b/src/patches/pcre-8.37-Fix-named-forward-reference-to-duplicate-group-numbe.patch new file mode 100644 index 0000000000..837e86f348 --- /dev/null +++ b/src/patches/pcre-8.37-Fix-named-forward-reference-to-duplicate-group-numbe.patch @@ -0,0 +1,98 @@ +From 83ed574998fe7b844b98ab7cd56291068feb9e31 Mon Sep 17 00:00:00 2001 +From: ph10 +Date: Sat, 16 May 2015 11:05:40 +0000 +Subject: [PATCH] Fix named forward reference to duplicate group number + overflow bug. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Port to 8.37: + +commit 2fa78aa4e42bcebf2d616c4ee89c012f29dc3447 +Author: ph10 +Date: Sat May 16 11:05:40 2015 +0000 + + Fix named forward reference to duplicate group number overflow bug. + + git-svn-id: svn://vcs.exim.org/pcre/code/trunk@1559 2f5784b3-3f2a-0410-8824-cb99058d5e15 + +Signed-off-by: Petr Písař +--- + pcre_compile.c | 24 ++++++++++++++++-------- + testdata/testinput1 | 3 +++ + testdata/testoutput1 | 5 +++++ + 3 files changed, 24 insertions(+), 8 deletions(-) + +diff --git a/pcre_compile.c b/pcre_compile.c +index b66b1f6..8b4aaef 100644 +--- a/pcre_compile.c ++++ b/pcre_compile.c +@@ -7183,15 +7183,15 @@ for (;; ptr++) + open_capitem *oc; + recno = ng->number; + if (is_recurse) break; +- for (oc = cd->open_caps; oc != NULL; oc = oc->next) +- { +- if (oc->number == recno) +- { +- oc->flag = TRUE; ++ for (oc = cd->open_caps; oc != NULL; oc = oc->next) ++ { ++ if (oc->number == recno) ++ { ++ oc->flag = TRUE; + break; +- } +- } +- } ++ } ++ } ++ } + } + + /* Count named back references. */ +@@ -7203,6 +7203,14 @@ for (;; ptr++) + 16-bit data item. */ + + *lengthptr += IMM2_SIZE; ++ ++ /* If this is a forward reference and we are within a (?|...) group, ++ the reference may end up as the number of a group which we are ++ currently inside, that is, it could be a recursive reference. In the ++ real compile this will be picked up and the reference wrapped with ++ OP_ONCE to make it atomic, so we must space in case this occurs. */ ++ ++ if (recno == 0) *lengthptr += 2 + 2*LINK_SIZE; + } + + /* In the real compile, search the name table. We check the name +diff --git a/testdata/testinput1 b/testdata/testinput1 +index 73c2f4d..8379ce0 100644 +--- a/testdata/testinput1 ++++ b/testdata/testinput1 +@@ -5730,4 +5730,7 @@ AbcdCBefgBhiBqz + "(?1)(?#?'){8}(a)" + baaaaaaaaac + ++"(?|(\k'Pm')|(?'Pm'))" ++ abcd ++ + /-- End of testinput1 --/ +diff --git a/testdata/testoutput1 b/testdata/testoutput1 +index 0a53fd0..e852ab9 100644 +--- a/testdata/testoutput1 ++++ b/testdata/testoutput1 +@@ -9429,4 +9429,9 @@ No match + 0: aaaaaaaaa + 1: a + ++"(?|(\k'Pm')|(?'Pm'))" ++ abcd ++ 0: ++ 1: ++ + /-- End of testinput1 --/ +-- +2.4.3 + -- 2.39.2