Author: ken Date: Thu Sep 3 13:28:09 2015 New Revision: 3269 Log: Fix buffer overflows in pcre. I bloated this by adding details of which various fedora patches which are included, and their order, just in case more problems are found before the next release.
Added: trunk/pcre/pcre-8.37-upstream_fixes-1.patch Added: trunk/pcre/pcre-8.37-upstream_fixes-1.patch ============================================================================== --- /dev/null 00:00:00 1970 (empty, because file is newly added) +++ trunk/pcre/pcre-8.37-upstream_fixes-1.patch Thu Sep 3 13:28:09 2015 (r3269) @@ -0,0 +1,282 @@ +Submitted By: Ken Moffat <ken at linuxfromscratch dot org> +Date: 2015-09-03 +Initial Package Version: 8.37 +Upstream Status: Applied +Origin: Upstream, via fedora +Description: Various buffer overflows, including CVE-2015-3210 and CVE-2015-5073. +Some of fixes these were backported to 8.37 by fedora. Some, or all, of the +issues also apply to several earlier versions of PCRE. + +This contains the following patches, applied in this order: + +pcre-8.37-Fix-buffer-overflow-for-named-recursive-back-referen.patch +(fixes CVE-2015-3210) + +pcre-8.37-Fix-buffer-overflow-for-forward-reference-within-bac.patch +(fixes CVE-2015-5073) + +pcre-8.37-Fix-named-forward-reference-to-duplicate-group-numbe.patch +pcre-8.37-Fix-another-buffer-overflow.patch +(these two are both required for this next one -) +pcre-8.37-Fix-buffer-overflow-for-named-references-in-situatio.patch +(prevents crashes, e.g. in pcretest or php, with a crafted regex) + +pcre-8.37-Hack-in-yet-other-patch-for-a-bug-in-size-computatio.patch + + +diff -Naur pcre-8.37.orig/pcre_compile.c pcre-8.37.patched/pcre_compile.c +--- pcre-8.37.orig/pcre_compile.c 2015-04-13 16:54:01.000000000 +0100 ++++ pcre-8.37.patched/pcre_compile.c 2015-09-03 18:35:01.007810651 +0100 +@@ -6641,6 +6641,7 @@ + /* ------------------------------------------------------------ */ + case CHAR_VERTICAL_LINE: /* Reset capture count for each branch */ + reset_bracount = TRUE; ++ cd->dupgroups = TRUE; /* Record (?| encountered */ + /* Fall through */ + + /* ------------------------------------------------------------ */ +@@ -7151,7 +7152,8 @@ + if (lengthptr != NULL) + { + named_group *ng; +- ++ recno = 0; ++ + if (namelen == 0) + { + *errorcodeptr = ERR62; +@@ -7168,20 +7170,6 @@ + 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. */ +- +- 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) +- break; +- } +- recno = (i < cd->names_found)? ng->number : 0; +- + /* Count named back references. */ + + if (!is_recurse) cd->namedrefcount++; +@@ -7191,6 +7179,56 @@ + 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. */ ++ ++ /* 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. */ ++ ++ *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 += 4 + 4*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 +@@ -7237,8 +7275,6 @@ + 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; + } +@@ -9164,6 +9200,7 @@ + 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; +@@ -9198,7 +9235,7 @@ + + DPRINTF(("end pre-compile: length=%d workspace=%d\n", length, + (int)(cd->hwm - cworkspace))); +- ++ + if (length > MAX_PATTERN_SIZE) + { + errorcode = ERR20; +@@ -9366,7 +9403,7 @@ + "const" attribute if the cast (pcre_uchar *)codestart is used directly in the + function call. */ + +-if ((options & PCRE_NO_AUTO_POSSESS) == 0) ++if (errorcode == 0 && (options & PCRE_NO_AUTO_POSSESS) == 0) + { + pcre_uchar *temp = (pcre_uchar *)codestart; + auto_possessify(temp, utf, cd); +@@ -9380,7 +9417,7 @@ + exceptional ones forgo this. We scan the pattern to check that they are fixed + length, and set their lengths. */ + +-if (cd->check_lookbehind) ++if (errorcode == 0 && cd->check_lookbehind) + { + pcre_uchar *cc = (pcre_uchar *)codestart; + +@@ -9593,4 +9630,3 @@ + } + + /* End of pcre_compile.c */ +- +diff -Naur pcre-8.37.orig/pcre_internal.h pcre-8.37.patched/pcre_internal.h +--- pcre-8.37.orig/pcre_internal.h 2015-04-14 18:06:44.000000000 +0100 ++++ pcre-8.37.patched/pcre_internal.h 2015-09-03 18:34:38.903811043 +0100 +@@ -2446,6 +2446,7 @@ + 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 -Naur pcre-8.37.orig/testdata/testinput1 pcre-8.37.patched/testdata/testinput1 +--- pcre-8.37.orig/testdata/testinput1 2015-03-29 12:25:15.000000000 +0100 ++++ pcre-8.37.patched/testdata/testinput1 2015-09-03 18:33:59.227811748 +0100 +@@ -5730,4 +5730,7 @@ + "(?1)(?#?'){8}(a)" + baaaaaaaaac + ++"(?|(\k'Pm')|(?'Pm'))" ++ abcd ++ + /-- End of testinput1 --/ +diff -Naur pcre-8.37.orig/testdata/testinput2 pcre-8.37.patched/testdata/testinput2 +--- pcre-8.37.orig/testdata/testinput2 2015-04-13 10:36:15.000000000 +0100 ++++ pcre-8.37.patched/testdata/testinput2 2015-09-03 18:35:01.007810651 +0100 +@@ -4152,4 +4152,14 @@ + + /((?2){73}(?2))((?1))/ + ++"(?J)(?'d'(?'d'\g{d}))" ++ ++/(?=di(?<=(?1))|(?=(.))))/ ++ ++"(?J:(?|(?'R')(\k'R')|((?'R'))))" ++ ++/(?J:(?|(:(?|(?'R')(\k'R')|((?'R')))H'Rk'Rf)|s(?'R')))/ ++ ++/(?J:(?|(:(?|(?'R')(\z(?|(?'R')(\k'R')|((?'R')))k'R')|((?'R')))H'Ak'Rf)|s(?'R')))/ ++ + /-- End of testinput2 --/ +diff -Naur pcre-8.37.orig/testdata/testoutput1 pcre-8.37.patched/testdata/testoutput1 +--- pcre-8.37.orig/testdata/testoutput1 2015-03-29 12:25:26.000000000 +0100 ++++ pcre-8.37.patched/testdata/testoutput1 2015-09-03 18:33:59.227811748 +0100 +@@ -9429,4 +9429,9 @@ + 0: aaaaaaaaa + 1: a + ++"(?|(\k'Pm')|(?'Pm'))" ++ abcd ++ 0: ++ 1: ++ + /-- End of testinput1 --/ +diff -Naur pcre-8.37.orig/testdata/testoutput11-16 pcre-8.37.patched/testdata/testoutput11-16 +--- pcre-8.37.orig/testdata/testoutput11-16 2015-03-02 17:09:21.000000000 +0000 ++++ pcre-8.37.patched/testdata/testoutput11-16 2015-09-03 18:34:19.207811393 +0100 +@@ -231,7 +231,7 @@ + ------------------------------------------------------------------ + + /(?P<a>a)...(?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 -Naur pcre-8.37.orig/testdata/testoutput11-32 pcre-8.37.patched/testdata/testoutput11-32 +--- pcre-8.37.orig/testdata/testoutput11-32 2015-03-02 17:09:30.000000000 +0000 ++++ pcre-8.37.patched/testdata/testoutput11-32 2015-09-03 18:34:19.207811393 +0100 +@@ -231,7 +231,7 @@ + ------------------------------------------------------------------ + + /(?P<a>a)...(?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 -Naur pcre-8.37.orig/testdata/testoutput11-8 pcre-8.37.patched/testdata/testoutput11-8 +--- pcre-8.37.orig/testdata/testoutput11-8 2015-03-02 17:09:13.000000000 +0000 ++++ pcre-8.37.patched/testdata/testoutput11-8 2015-09-03 18:34:19.207811393 +0100 +@@ -231,7 +231,7 @@ + ------------------------------------------------------------------ + + /(?P<a>a)...(?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 -Naur pcre-8.37.orig/testdata/testoutput2 pcre-8.37.patched/testdata/testoutput2 +--- pcre-8.37.orig/testdata/testoutput2 2015-04-13 10:36:27.000000000 +0100 ++++ pcre-8.37.patched/testdata/testoutput2 2015-09-03 18:35:01.007810651 +0100 +@@ -14423,4 +14423,15 @@ + + /((?2){73}(?2))((?1))/ + ++"(?J)(?'d'(?'d'\g{d}))" ++ ++/(?=di(?<=(?1))|(?=(.))))/ ++Failed: unmatched parentheses at offset 23 ++ ++"(?J:(?|(?'R')(\k'R')|((?'R'))))" ++ ++/(?J:(?|(:(?|(?'R')(\k'R')|((?'R')))H'Rk'Rf)|s(?'R')))/ ++ ++/(?J:(?|(:(?|(?'R')(\z(?|(?'R')(\k'R')|((?'R')))k'R')|((?'R')))H'Ak'Rf)|s(?'R')))/ ++ + /-- End of testinput2 --/ -- http://lists.linuxfromscratch.org/listinfo/patches FAQ: http://www.linuxfromscratch.org/blfs/faq.html Unsubscribe: See the above information page