In perl.git, the branch blead has been updated <http://perl5.git.perl.org/perl.git/commitdiff/db58a81c116b9bdc669c1b1a8cb7fd33627a926b?hp=ab3ebe974fa603224393cc703dcf1d58a58db38a>
- Log ----------------------------------------------------------------- commit db58a81c116b9bdc669c1b1a8cb7fd33627a926b Author: David Mitchell <[email protected]> Date: Fri Dec 19 22:52:55 2014 +0000 fix integer overflow in S_regpiece(). RExC_naughty is incremented when nasty bits of regex are found. If at the end of compilation, its > 01, then PREGf_NAUGHTY is set on the pattern. However, some bits of S_regpiece on detecting naughiness, double or nearly double RExC_naughty, quickly resulting in overflow of the I32. I've fixed it by skipping the doubling when RExC_naughty is large, but I don't know whether the doubling is conceptually wrong in the first place. Found by -fsanitize=undefined. M regcomp.c commit a1b2073ef1dbfca70742296d373883902e6188b7 Author: David Mitchell <[email protected]> Date: Fri Dec 19 22:35:48 2014 +0000 fix integer overflow in S_study_chunk(). It was adding to delta even when delta was already SSize_t_MAX This triggered it: /.*(ab|abc)/. Found by -fsanitize=undefined. M regcomp.c commit 55b6a5f665b57d91246b00d58d8bf9ba32c7cdc3 Author: David Mitchell <[email protected]> Date: Fri Dec 19 22:19:58 2014 +0000 fix integer overflow in S_study_chunk(). It was adding SSize_t_MAX to data->last_start_max when data->last_start_max was already SSize_t_MAX. This triggered it: /(x+y)+/. Found by -fsanitize=undefined. M regcomp.c commit 646e87871404a31d5a6c6ac42ca921078d055354 Author: David Mitchell <[email protected]> Date: Fri Dec 19 21:41:11 2014 +0000 fix integer overflow in S_scan_commit(). offset_float_max could end up as SSize_t_MAX+1. This triggered it: /^x(ab|c.+)$/. Found by -fsanitize=undefined. M regcomp.c commit 2e2c882dd53d6b966a0cd3b0ef111ff9e85f2c41 Author: David Mitchell <[email protected]> Date: Fri Dec 19 20:31:00 2014 +0000 add asan_ignore - which errors to ignore "clang -fsanitize=undefined" produces lots of false positives. This file allows certain functions to be excluded from checking. Use it as: clang -fsanitize=undefined -fsanitize-blacklist=`pwd`/asan_ignore M MANIFEST A asan_ignore ----------------------------------------------------------------------- Summary of changes: MANIFEST | 1 + asan_ignore | 19 +++++++++++++++++++ regcomp.c | 20 +++++++++++++------- 3 files changed, 33 insertions(+), 7 deletions(-) create mode 100644 asan_ignore diff --git a/MANIFEST b/MANIFEST index 844b7ae..b3f0f2d 100644 --- a/MANIFEST +++ b/MANIFEST @@ -1,4 +1,5 @@ Artistic The "Artistic License" +asan_ignore Errors to skip under clang's Addresss Sanitizer AUTHORS Contact info for contributors autodoc.pl Creates pod/perlintern.pod and pod/perlapi.pod av.c Array value code diff --git a/asan_ignore b/asan_ignore new file mode 100644 index 0000000..5a8bc5c --- /dev/null +++ b/asan_ignore @@ -0,0 +1,19 @@ +# This file intended to be used with clang as +# +# clang -fsanitize=foo -fsanitize-blacklist=`pwd`/asan_ignore +# +# It lists those files / functions that clang's Address Sanitizer should +# ignore. +# +# See http://clang.llvm.org/docs/SanitizerSpecialCaseList.html. + + +# The pp functions used under 'use integer' shouldn't warn about +# integer overflow etc. +# +# Unfortunately there doesn't seem to be any way to disable just specific +# errors (i.e. the integer overflow ones). The manual implies that you can +# suffix with =foo for a "tool-specific category", but neither =undefined +# nor =signed-integer-overflow worked. + +fun:Perl_pp_i_* diff --git a/regcomp.c b/regcomp.c index e5d6a76..8e146ac 100644 --- a/regcomp.c +++ b/regcomp.c @@ -928,8 +928,8 @@ S_scan_commit(pTHX_ const RExC_state_t *pRExC_state, scan_data_t *data, else { /* *data->longest == data->longest_float */ data->offset_float_min = l ? data->last_start_min : data->pos_min; data->offset_float_max = (l - ? data->last_start_max - : (data->pos_delta == SSize_t_MAX + ? data->last_start_max + : (data->pos_delta > SSize_t_MAX - data->pos_min ? SSize_t_MAX : data->pos_min + data->pos_delta)); if (is_inf @@ -4888,8 +4888,11 @@ S_study_chunk(pTHX_ RExC_state_t *pRExC_state, regnode **scanp, } else { /* start offset must point into the last copy */ data->last_start_min += minnext * (mincount - 1); - data->last_start_max += is_inf ? SSize_t_MAX - : (maxcount - 1) * (minnext + data->pos_delta); + data->last_start_max = + is_inf + ? SSize_t_MAX + : data->last_start_max + + (maxcount - 1) * (minnext + data->pos_delta); } } /* It is counted once already... */ @@ -5511,7 +5514,8 @@ PerlIO_printf(Perl_debug_log, "LHS=%"UVuf" RHS=%"UVuf"\n", data->longest = &(data->longest_float); } min += min1; - delta += max1 - min1; + if (delta != SSize_t_MAX) + delta += max1 - min1; if (flags & SCF_DO_STCLASS_OR) { ssc_or(pRExC_state, data->start_class, (regnode_charclass *) &accum); if (min1) { @@ -10855,7 +10859,8 @@ S_regpiece(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth) do_curly: if ((flags&SIMPLE)) { - RExC_naughty += 2 + RExC_naughty / 2; + if (RExC_naughty < I32_MAX / 2) + RExC_naughty += 2 + RExC_naughty / 2; reginsert(pRExC_state, CURLY, ret, depth+1); Set_Node_Offset(ret, parse_start+1); /* MJD */ Set_Node_Cur_Length(ret, parse_start); @@ -10881,7 +10886,8 @@ S_regpiece(pTHX_ RExC_state_t *pRExC_state, I32 *flagp, U32 depth) REGTAIL(pRExC_state, ret, reg_node(pRExC_state, NOTHING)); if (SIZE_ONLY) RExC_whilem_seen++, RExC_extralen += 3; - RExC_naughty += 4 + RExC_naughty; /* compound interest */ + if (RExC_naughty < I32_MAX / 4) + RExC_naughty += 4 + RExC_naughty; /* compound interest */ } ret->flags = 0; -- Perl5 Master Repository
