In perl.git, the branch blead has been updated <http://perl5.git.perl.org/perl.git/commitdiff/42e9b60980bb8e29e76629e14c6aa945194c0647?hp=d7f10d93694c1509945bc189993708c89f7a1df3>
- Log ----------------------------------------------------------------- commit 42e9b60980bb8e29e76629e14c6aa945194c0647 Author: Hugo van der Sanden <[email protected]> Date: Wed Oct 5 02:20:26 2016 +0100 [perl #129061] CURLYX nodes can be studied more than once study_chunk() for CURLYX is used to set flags on the linked WHILEM node to say it is the whilem_c'th of whilem_seen. However it assumes each CURLYX can be studied only once, which is not the case - there are various cases such as GOSUB which call study_chunk() recursively on already-visited parts of the program. Storing the wrong index can cause the super-linear cache handling in regmatch() to read/write the byte after the end of poscache. Also reported in [perl #129281]. M regcomp.c M t/re/pat.t commit d2ba660af00f1bf2e7012741615eff7c19f29707 Author: Tony Cook <[email protected]> Date: Mon Oct 10 10:46:46 2016 +1100 (perl #129281) test for buffer overflow issue M t/re/pat.t commit 10ef0e307fe8eca589d532ca748eb60788312bed Author: Hugo van der Sanden <[email protected]> Date: Mon Feb 6 11:11:11 2017 +0000 vi hints for pat.t M t/re/pat.t ----------------------------------------------------------------------- Summary of changes: regcomp.c | 12 +++++++++--- t/re/pat.t | 10 +++++++++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/regcomp.c b/regcomp.c index 850a6c1544..48c8d8da04 100644 --- a/regcomp.c +++ b/regcomp.c @@ -5218,15 +5218,21 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp, However, this time it's not a subexpression we care about, but the expression itself. */ && (maxcount == REG_INFTY) - && data && ++data->whilem_c < 16) { + && data) { /* This stays as CURLYX, we can put the count/of pair. */ /* Find WHILEM (as in regexec.c) */ regnode *nxt = oscan + NEXT_OFF(oscan); if (OP(PREVOPER(nxt)) == NOTHING) /* LONGJMP */ nxt += ARG(nxt); - PREVOPER(nxt)->flags = (U8)(data->whilem_c - | (RExC_whilem_seen << 4)); /* On WHILEM */ + nxt = PREVOPER(nxt); + if (nxt->flags & 0xf) { + /* we've already set whilem count on this node */ + } else if (++data->whilem_c < 16) { + assert(data->whilem_c <= RExC_whilem_seen); + nxt->flags = (U8)(data->whilem_c + | (RExC_whilem_seen << 4)); /* On WHILEM */ + } } if (data && fl & (SF_HAS_PAR|SF_IN_PAR)) pars++; diff --git a/t/re/pat.t b/t/re/pat.t index 9abe5aa119..16bfc8e773 100644 --- a/t/re/pat.t +++ b/t/re/pat.t @@ -23,7 +23,7 @@ BEGIN { skip_all('no re module') unless defined &DynaLoader::boot_DynaLoader; skip_all_without_unicode_tables(); -plan tests => 836; # Update this when adding/deleting tests. +plan tests => 837; # Update this when adding/deleting tests. run_tests() unless caller; @@ -1907,6 +1907,14 @@ EOP "Unmatched [ in regex; marked by <-- HERE in m/[ <-- HERE (?{/ at (eval 1) line 1.\n", {}, "buffer overflow for regexp component"); } + { + # [perl #129281] buffer write overflow, detected by ASAN, valgrind + fresh_perl_is('/0(?0)|^*0(?0)|^*(^*())0|/', '', {}, "don't bump whilem_c too much"); + } } # End of sub run_tests 1; + +# +# ex: set ts=8 sts=4 sw=4 et: +# -- Perl5 Master Repository
