From cdefe642dc2e6b5b8e6703773934813f317bc488 Mon Sep 17 00:00:00 2001 From: ph10 Date: Thu, 4 Jul 2019 17:01:53 +0000 Subject: [PATCH] Check for integer overflow when computing lookbehind lengths. Fixes Clusterfuzz issue 13656. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit git-svn-id: svn://vcs.exim.org/pcre2/code/trunk@1126 6239d852-aaf2-0410-a92c-79f79f948069 Petr Písař: Ported to 10.33. Signed-off-by: Petr Písař --- src/pcre2_compile.c | 38 ++++++++++++++++++++++++++++---------- testdata/testinput2 | 2 ++ testdata/testoutput2 | 3 +++ 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/pcre2_compile.c b/src/pcre2_compile.c index c82c6ca..f6e0a0b 100644 --- a/src/pcre2_compile.c +++ b/src/pcre2_compile.c @@ -9197,8 +9197,26 @@ for (;; pptr++) case META_MINMAX_QUERY: if (pptr[1] == pptr[2]) { - if (pptr[1] == 0) branchlength -= lastitemlength; - else itemlength = (pptr[1] - 1) * lastitemlength; + switch(pptr[1]) + { + case 0: + branchlength -= lastitemlength; + break; + + case 1: + itemlength = 0; + break; + + default: /* Check for integer overflow */ + if (lastitemlength != 0 && /* Should not occur, but just in case */ + INT_MAX/lastitemlength < pptr[1] - 1) + { + *errcodeptr = ERR87; /* Integer overflow; lookbehind too big */ + return -1; + } + itemlength = (pptr[1] - 1) * lastitemlength; + break; + } pptr += 2; break; } @@ -9212,19 +9230,19 @@ for (;; pptr++) return -1; } - /* Add the item length to the branchlength, and save it for use if the next - thing is a quantifier. */ - - branchlength += itemlength; - lastitemlength = itemlength; - - /* Ensure that the length does not overflow the limit. */ + /* Add the item length to the branchlength, checking for integer overflow and + for the branch length exceeding the limit. */ - if (branchlength > LOOKBEHIND_MAX) + if (INT_MAX - branchlength < (int)itemlength || + (branchlength += itemlength) > LOOKBEHIND_MAX) { *errcodeptr = ERR87; return -1; } + + /* Save this item length for use if the next item is a quantifier. */ + + lastitemlength = itemlength; } EXIT: diff --git a/testdata/testinput2 b/testdata/testinput2 index 8a98f94..079d6d8 100644 --- a/testdata/testinput2 +++ b/testdata/testinput2 @@ -5591,4 +5591,6 @@ a)"xI /\[()]{65535}(?)/expand +/( {32742} {42})(?)/expand Failed: error 197 at offset 131075: too many capturing groups (maximum 65535) +/( {32742} {42})(?