Skip to content

Commit 3665ab0

Browse files
committed
Fix GH-15657: Segmentation fault in ext/opcache/jit/ir/dynasm/dasm_x86.h
The crash happens because the zend_persist.c code tries to JIT the hook's op_array while the JIT buffer memory is still protected. This happens in `zend_persist_property_info` called via `zend_persist_class_entry` through the inheritance cache. We shouldn't JIT the property hook code when persisting property info for the inheritance cache. This is a simple workaround by temporarily disabling the JIT so that the property hook code is not JITted when persisting the property info. An alternative solution would be to move the JITting of the property hooks to a different place in zend_persist.c by doing an additional pass over the classes. Closes GH-15819.
1 parent dc5f3b9 commit 3665ab0

File tree

3 files changed

+38
-0
lines changed

3 files changed

+38
-0
lines changed

NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ PHP NEWS
22
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
33
?? ??? ????, PHP 8.4.0RC1
44

5+
- Opcache:
6+
. Fixed bug GH-15657 (Segmentation fault in dasm_x86.h). (nielsdos)
7+
58
12 Sep 2024, PHP 8.4.0beta5
69

710
- BCMath:

ext/opcache/ZendAccelerator.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2428,9 +2428,22 @@ static zend_class_entry* zend_accel_inheritance_cache_add(zend_class_entry *ce,
24282428
} ZEND_HASH_FOREACH_END();
24292429
ZCG(mem) = (char*)ZCG(mem) + zend_hash_num_elements(dependencies) * sizeof(zend_class_dependency);
24302430
}
2431+
2432+
/* See GH-15657: `zend_persist_class_entry` can JIT property hook code via
2433+
* `zend_persist_property_info`, but the inheritance cache should not
2434+
* JIT those at this point in time. */
2435+
#ifdef HAVE_JIT
2436+
bool jit_on_old = JIT_G(on);
2437+
JIT_G(on) = false;
2438+
#endif
2439+
24312440
entry->ce = new_ce = zend_persist_class_entry(ce);
24322441
zend_update_parent_ce(new_ce);
24332442

2443+
#ifdef HAVE_JIT
2444+
JIT_G(on) = jit_on_old;
2445+
#endif
2446+
24342447
entry->num_warnings = EG(num_errors);
24352448
entry->warnings = zend_persist_warnings(EG(num_errors), EG(errors));
24362449
entry->next = proto->inheritance_cache;

ext/opcache/tests/jit/gh15657.phpt

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
--TEST--
2+
GH-15657 (Segmentation fault in ext/opcache/jit/ir/dynasm/dasm_x86.h)
3+
--EXTENSIONS--
4+
opcache
5+
--INI--
6+
opcache.jit_buffer_size=64M
7+
opcache.jit=1101
8+
--FILE--
9+
<?php
10+
// Triggering the inheritance cache via implementing this interface is important to reproduce the bug
11+
interface I {}
12+
13+
class A implements I {
14+
private $_prop;
15+
public $prop {
16+
get => $this->_prop;
17+
}
18+
}
19+
echo "Done\n";
20+
?>
21+
--EXPECT--
22+
Done

0 commit comments

Comments
 (0)