From c1ffd4b484e498fbd614587421df247b41e6bb96 Mon Sep 17 00:00:00 2001 From: Niels Dossche <7771979+nielsdos@users.noreply.github.com> Date: Fri, 6 Sep 2024 23:40:25 +0200 Subject: [PATCH] Fix GH-15658: Segmentation fault in Zend/zend_vm_execute.h Implement a minimal ZEND_MATCH handler using a tail call. Closes GH-15782. --- NEWS | 2 ++ ext/opcache/jit/zend_jit.c | 6 ++++++ ext/opcache/tests/jit/gh15658.phpt | 15 +++++++++++++++ 3 files changed, 23 insertions(+) create mode 100644 ext/opcache/tests/jit/gh15658.phpt diff --git a/NEWS b/NEWS index e534d3efcd8..0be046b5842 100644 --- a/NEWS +++ b/NEWS @@ -33,6 +33,8 @@ PHP NEWS - Opcache: . Fixed bug GH-15661 (Access null pointer in Zend/Optimizer/zend_inference.c). (nielsdos) + . Fixed bug GH-15658 (Segmentation fault in Zend/zend_vm_execute.h). + (nielsdos) - Standard: . Fixed bug GH-15552 (Signed integer overflow in ext/standard/scanf.c). (cmb) diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index 39d3145275c..ccfde3d47ad 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -3970,7 +3970,13 @@ static int zend_jit(const zend_op_array *op_array, zend_ssa *ssa, const zend_op case ZEND_OP_DATA: case ZEND_SWITCH_LONG: case ZEND_SWITCH_STRING: + break; case ZEND_MATCH: + /* We have to exit to the VM because the MATCH handler performs an N-way jump for + * which we can't generate simple (opcache.jit=1201) JIT code. */ + if (!zend_jit_tail_handler(&dasm_state, opline)) { + goto jit_failure; + } break; case ZEND_JMP: if (JIT_G(opt_level) < ZEND_JIT_LEVEL_INLINE) { diff --git a/ext/opcache/tests/jit/gh15658.phpt b/ext/opcache/tests/jit/gh15658.phpt new file mode 100644 index 00000000000..a5a5793a9aa --- /dev/null +++ b/ext/opcache/tests/jit/gh15658.phpt @@ -0,0 +1,15 @@ +--TEST-- +GH-15658 (Segmentation fault in Zend/zend_vm_execute.h) +--EXTENSIONS-- +opcache +--INI-- +opcache.jit=0101 +opcache.jit_buffer_size=1024M +--FILE-- + 'foo', +}; +?> +--EXPECT-- +foo