Fix infinite recursion in the JIT compiler when certain patterns when certain patterns are analysed.

This commit is contained in:
Zoltán Herczeg 2015-07-20 07:38:06 +00:00
parent 21b15d96f2
commit f957e7bfa8
4 changed files with 18 additions and 4 deletions

View File

@ -50,6 +50,9 @@ Persch).
provoke a buffer overflow. This bug was discovered by Karl Skomski with the provoke a buffer overflow. This bug was discovered by Karl Skomski with the
LLVM fuzzer. LLVM fuzzer.
14. Fix infinite recursion in the JIT compiler when certain patterns such as
/(?:|a|){100}x/ are analysed.
Version 10.20 30-June-2015 Version 10.20 30-June-2015
-------------------------- --------------------------

View File

@ -3340,7 +3340,7 @@ bytes[len] = byte;
bytes[0] = len; bytes[0] = len;
} }
static int scan_prefix(compiler_common *common, PCRE2_SPTR cc, sljit_ui *chars, sljit_ub *bytes, int max_chars) static int scan_prefix(compiler_common *common, PCRE2_SPTR cc, sljit_ui *chars, sljit_ub *bytes, int max_chars, uint32_t *rec_count)
{ {
/* Recursive function, which scans prefix literals. */ /* Recursive function, which scans prefix literals. */
BOOL last, any, caseless; BOOL last, any, caseless;
@ -3358,9 +3358,14 @@ PCRE2_UCHAR othercase[1];
repeat = 1; repeat = 1;
while (TRUE) while (TRUE)
{ {
if (*rec_count == 0)
return 0;
rec_count--;
last = TRUE; last = TRUE;
any = FALSE; any = FALSE;
caseless = FALSE; caseless = FALSE;
switch (*cc) switch (*cc)
{ {
case OP_CHARI: case OP_CHARI:
@ -3422,7 +3427,7 @@ while (TRUE)
#ifdef SUPPORT_UNICODE #ifdef SUPPORT_UNICODE
if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc); if (common->utf && HAS_EXTRALEN(*cc)) len += GET_EXTRALEN(*cc);
#endif #endif
max_chars = scan_prefix(common, cc + len, chars, bytes, max_chars); max_chars = scan_prefix(common, cc + len, chars, bytes, max_chars, rec_count);
if (max_chars == 0) if (max_chars == 0)
return consumed; return consumed;
last = FALSE; last = FALSE;
@ -3445,7 +3450,7 @@ while (TRUE)
alternative = cc + GET(cc, 1); alternative = cc + GET(cc, 1);
while (*alternative == OP_ALT) while (*alternative == OP_ALT)
{ {
max_chars = scan_prefix(common, alternative + 1 + LINK_SIZE, chars, bytes, max_chars); max_chars = scan_prefix(common, alternative + 1 + LINK_SIZE, chars, bytes, max_chars, rec_count);
if (max_chars == 0) if (max_chars == 0)
return consumed; return consumed;
alternative += GET(alternative, 1); alternative += GET(alternative, 1);
@ -3690,6 +3695,7 @@ int i, max, from;
int range_right = -1, range_len = 3 - 1; int range_right = -1, range_len = 3 - 1;
sljit_ub *update_table = NULL; sljit_ub *update_table = NULL;
BOOL in_range; BOOL in_range;
uint32_t rec_count;
for (i = 0; i < MAX_N_CHARS; i++) for (i = 0; i < MAX_N_CHARS; i++)
{ {
@ -3698,7 +3704,8 @@ for (i = 0; i < MAX_N_CHARS; i++)
bytes[i * MAX_N_BYTES] = 0; bytes[i * MAX_N_BYTES] = 0;
} }
max = scan_prefix(common, common->start, chars, bytes, MAX_N_CHARS); rec_count = 10000;
max = scan_prefix(common, common->start, chars, bytes, MAX_N_CHARS, &rec_count);
if (max <= 1) if (max <= 1)
return FALSE; return FALSE;

View File

@ -202,4 +202,6 @@
/(a(?:a|b|c|d|e)b){8,16}/jit=1 /(a(?:a|b|c|d|e)b){8,16}/jit=1
/(?:|a|){100}x/jit=1
# End of testinput16 # End of testinput16

View File

@ -381,4 +381,6 @@ JIT compilation was successful
/(a(?:a|b|c|d|e)b){8,16}/jit=1 /(a(?:a|b|c|d|e)b){8,16}/jit=1
/(?:|a|){100}x/jit=1
# End of testinput16 # End of testinput16