diff --git a/perl-5.26.2-PATCH-perl-133185-Infinite-loop-in-qr.patch b/perl-5.26.2-PATCH-perl-133185-Infinite-loop-in-qr.patch new file mode 100644 index 0000000..427553e --- /dev/null +++ b/perl-5.26.2-PATCH-perl-133185-Infinite-loop-in-qr.patch @@ -0,0 +1,105 @@ +From dc1f8f6b581a8e4efbb782398ab3e7c3a52b062f Mon Sep 17 00:00:00 2001 +From: Karl Williamson +Date: Tue, 8 May 2018 12:13:18 -0600 +Subject: [PATCH] PATCH: [perl #133185] Infinite loop in qr// +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This loop was inadvertently introduced as part of patches to fix +(perl #132227 CVE-2018-6797] heap-buffer-overflow". The commit in 5.27 +responsible was f8fb8615ddc5a80e3bbd4386a8914497f921b62d. + +To be vulnerable, the pattern must start out as /d (hence no use 5.012 +or higher), and then there must be something that implicitly forces /u +(which the \pp does in the test case added by this patch), and then +(?aa), and then the code point \xDF. (German Sharp S). The /i must be +in effect by the time the DF is encountered, but it needn't come in the +(?aa) which the test does. + +The problem is that the conditional that is testing that we switched +away from /d rules is assuming that this happened during the +construction of the current EXACTFish node. The comments I wrote +indicate this assumption. But this example shows that the switch can +come before this node started getting constructed, and so it loops. + +The patch explicitly saves the state at the beginning of this node's +construction, and only retries if it changed during that construction. +Therefore the next time through, it will see that it hasn't changed +since the previous time, and won't loop. + +Petr Písař: Ported to 5.26.2 from: + +commit 0b9cb33b146b3eb55634853f883a880771dd1413 +Author: Karl Williamson +Date: Tue May 8 12:13:18 2018 -0600 + + PATCH: [perl #133185] Infinite loop in qr// + +Signed-off-by: Petr Písař +--- + regcomp.c | 10 +++++++++- + t/re/speed.t | 5 ++++- + 2 files changed, 13 insertions(+), 2 deletions(-) + +diff --git a/regcomp.c b/regcomp.c +index 845e660..18fa465 100644 +--- a/regcomp.c ++++ b/regcomp.c +@@ -13100,6 +13100,10 @@ S_regatom(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth) + bool maybe_exactfu = PASS2 + && (node_type == EXACTF || node_type == EXACTFL); + ++ /* To see if RExC_uni_semantics changes during parsing of the node. ++ * */ ++ bool uni_semantics_at_node_start; ++ + /* If a folding node contains only code points that don't + * participate in folds, it can be changed into an EXACT node, + * which allows the optimizer more things to look for */ +@@ -13147,6 +13151,8 @@ S_regatom(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth) + || UTF8_IS_INVARIANT(UCHARAT(RExC_parse)) + || UTF8_IS_START(UCHARAT(RExC_parse))); + ++ uni_semantics_at_node_start = RExC_uni_semantics; ++ + /* Here, we have a literal character. Find the maximal string of + * them in the input that we can fit into a single EXACTish node. + * We quit at the first non-literal or when the node gets full */ +@@ -13550,7 +13556,9 @@ S_regatom(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth) + * didn't think it needed to reparse. But this + * sharp s now does indicate the need for + * reparsing. */ +- if (RExC_uni_semantics) { ++ if ( uni_semantics_at_node_start ++ != RExC_uni_semantics) ++ { + p = oldp; + goto loopdone; + } +diff --git a/t/re/speed.t b/t/re/speed.t +index 4a4830f..9a57de1 100644 +--- a/t/re/speed.t ++++ b/t/re/speed.t +@@ -24,7 +24,7 @@ BEGIN { + skip_all('no re module') unless defined &DynaLoader::boot_DynaLoader; + skip_all_without_unicode_tables(); + +-plan tests => 58; #** update watchdog timeouts proportionally when adding tests ++plan tests => 59; #** update watchdog timeouts proportionally when adding tests + + use strict; + use warnings; +@@ -156,6 +156,9 @@ PROG + ok( $elapsed <= 1, "should not COW on long string with substr and m//g"); + } + ++ # [perl #133185] Infinite loop ++ like("!\xdf", eval 'qr/\pp(?aai)\xdf/', ++ 'Compiling qr/\pp(?aai)\xdf/ doesn\'t loop'); + + } # End of sub run_tests + +-- +2.14.3 + diff --git a/perl.spec b/perl.spec index 5ce0619..fe51d18 100644 --- a/perl.spec +++ b/perl.spec @@ -81,7 +81,7 @@ License: GPL+ or Artistic Epoch: %{perl_epoch} Version: %{perl_version} # release number must be even higher, because dual-lived modules will be broken otherwise -Release: 413%{?dist} +Release: 414%{?dist} Summary: Practical Extraction and Report Language Url: http://www.perl.org/ Source0: http://www.cpan.org/src/5.0/perl-%{perl_version}.tar.bz2 @@ -271,6 +271,10 @@ Patch83: perl-5.27.10-PATCH-perl-132167-Parse-error-in-regex_sets.patch # in upstream after 5.27.10 Patch84: perl-5.27.10-PATCH-perl-133074-5.26.1-some-coverity-fixes.patch +# Fix an infinite loop in the regular expression compiler, RT#133185, +# in upstream after 5.27.11 +Patch85: perl-5.26.2-PATCH-perl-133185-Infinite-loop-in-qr.patch + # Link XS modules to libperl.so with EU::CBuilder on Linux, bug #960048 Patch200: perl-5.16.3-Link-XS-modules-to-libperl.so-with-EU-CBuilder-on-Li.patch @@ -2876,6 +2880,7 @@ Perl extension for Version Objects %patch82 -p1 %patch83 -p1 %patch84 -p1 +%patch85 -p1 %patch200 -p1 %patch201 -p1 @@ -2928,6 +2933,7 @@ perl -x patchlevel.h \ 'Fedora Patch82: Fix line numbers in multi-line s/// (RT#131930)' \ 'Fedora Patch83: Fix parsing extended bracketed character classes (RT#132167)' \ 'Fedora Patch84: Fix a possibly unitialized memory read in the Perl parser (RT#133074)' \ + 'Fedora Patch85: Fix an infinite loop in the regular expression compiler (RT#133185)' \ 'Fedora Patch200: Link XS modules to libperl.so with EU::CBuilder on Linux' \ 'Fedora Patch201: Link XS modules to libperl.so with EU::MM on Linux' \ %{nil} @@ -5215,6 +5221,9 @@ popd # Old changelog entries are preserved in CVS. %changelog +* Fri May 25 2018 Petr Pisar - 4:5.26.2-414 +- Fix an infinite loop in the regular expression compiler (RT#133185) + * Fri May 18 2018 Jitka Plesnikova - 4:5.26.2-413 - Correct license tags of perl-libs (bug #1579524)