mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
Fix GH-14361: Deep recursion in zend_cfg.c causes segfault
Changes the CFG reachability algorithm to use iteration instead of recursion. Closes GH-14432.
This commit is contained in:
parent
2a02d35c2a
commit
a3b148e38d
2 changed files with 16 additions and 15 deletions
2
NEWS
2
NEWS
|
@ -121,6 +121,8 @@ PHP NEWS
|
||||||
64bit archs. (Arnaud)
|
64bit archs. (Arnaud)
|
||||||
. Fixed bug GH-13834 (Applying non-zero offset 36 to null pointer in
|
. Fixed bug GH-13834 (Applying non-zero offset 36 to null pointer in
|
||||||
zend_jit.c). (nielsdos)
|
zend_jit.c). (nielsdos)
|
||||||
|
. Fixed bug GH-14361 (Deep recursion in zend_cfg.c causes segfault).
|
||||||
|
(nielsdos)
|
||||||
|
|
||||||
- OpenSSL:
|
- OpenSSL:
|
||||||
. Fixed bug #80269 (OpenSSL sets Subject wrong with extraattribs parameter).
|
. Fixed bug #80269 (OpenSSL sets Subject wrong with extraattribs parameter).
|
||||||
|
|
|
@ -28,13 +28,20 @@ static void zend_mark_reachable(zend_op *opcodes, zend_cfg *cfg, zend_basic_bloc
|
||||||
{
|
{
|
||||||
zend_basic_block *blocks = cfg->blocks;
|
zend_basic_block *blocks = cfg->blocks;
|
||||||
|
|
||||||
while (1) {
|
zend_worklist work;
|
||||||
|
ALLOCA_FLAG(list_use_heap)
|
||||||
|
ZEND_WORKLIST_ALLOCA(&work, cfg->blocks_count, list_use_heap);
|
||||||
|
|
||||||
|
zend_worklist_push(&work, b - cfg->blocks);
|
||||||
|
|
||||||
|
while (zend_worklist_len(&work)) {
|
||||||
int i;
|
int i;
|
||||||
|
b = cfg->blocks + zend_worklist_pop(&work);
|
||||||
|
|
||||||
b->flags |= ZEND_BB_REACHABLE;
|
b->flags |= ZEND_BB_REACHABLE;
|
||||||
if (b->successors_count == 0) {
|
if (b->successors_count == 0) {
|
||||||
b->flags |= ZEND_BB_EXIT;
|
b->flags |= ZEND_BB_EXIT;
|
||||||
return;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < b->successors_count; i++) {
|
for (i = 0; i < b->successors_count; i++) {
|
||||||
|
@ -86,22 +93,14 @@ static void zend_mark_reachable(zend_op *opcodes, zend_cfg *cfg, zend_basic_bloc
|
||||||
succ->flags |= ZEND_BB_FOLLOW;
|
succ->flags |= ZEND_BB_FOLLOW;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i == b->successors_count - 1) {
|
/* Check reachability of successor */
|
||||||
/* Tail call optimization */
|
if (!(succ->flags & ZEND_BB_REACHABLE)) {
|
||||||
if (succ->flags & ZEND_BB_REACHABLE) {
|
zend_worklist_push(&work, succ - cfg->blocks);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
b = succ;
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
/* Recursively check reachability */
|
|
||||||
if (!(succ->flags & ZEND_BB_REACHABLE)) {
|
|
||||||
zend_mark_reachable(opcodes, cfg, succ);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ZEND_WORKLIST_FREE_ALLOCA(&work, list_use_heap);
|
||||||
}
|
}
|
||||||
/* }}} */
|
/* }}} */
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue