Skip to content

Commit 50c7f49

Browse files
committed
Reset Z_EXTRA_P(op2) of ZEND_INIT_FCALL for opcache file cache
The offset becomes stale if the environment changes. We're currently relying on other factors in the environment staying constant, e.g. send types. But this seems to be the worst offender. Partially addresses phpGH-17733 Closes phpGH-20328
1 parent a5e1baf commit 50c7f49

File tree

2 files changed

+22
-1
lines changed

2 files changed

+22
-1
lines changed

NEWS

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ PHP NEWS
5555
. Fixed bug GH-19875 (JIT 1205 segfault on large file compiled in subprocess).
5656
(Arnaud)
5757
. Fixed bug GH-20012 (heap buffer overflow in jit). (Arnaud)
58+
. Partially fixed bug GH-17733 (Avoid calling wrong function when reusing file
59+
caches across differing environments). (ilutov)
5860

5961
- PgSql:
6062
. Fix memory leak when first string conversion fails. (nielsdos)

ext/opcache/zend_file_cache.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -535,13 +535,32 @@ static void zend_file_cache_serialize_op_array(zend_op_array *op_arra
535535
}
536536
if (opline->op2_type == IS_CONST) {
537537
SERIALIZE_PTR(opline->op2.zv);
538+
539+
/* See GH-17733. Reset Z_EXTRA_P(op2) of ZEND_INIT_FCALL, which
540+
* is an offset into the global function table, to avoid calling
541+
* incorrect functions when environment changes. This, and the
542+
* equivalent code below, can be removed once proper system ID
543+
* validation is implemented. */
544+
if (opline->opcode == ZEND_INIT_FCALL) {
545+
zval *op2 = opline->op2.zv;
546+
UNSERIALIZE_PTR(op2);
547+
Z_EXTRA_P(op2) = 0;
548+
ZEND_VM_SET_OPCODE_HANDLER(opline);
549+
}
538550
}
539551
#else
540552
if (opline->op1_type == IS_CONST) {
541553
opline->op1.constant = RT_CONSTANT(opline, opline->op1) - literals;
542554
}
543555
if (opline->op2_type == IS_CONST) {
544-
opline->op2.constant = RT_CONSTANT(opline, opline->op2) - literals;
556+
zval *op2 = RT_CONSTANT(opline, opline->op2);
557+
opline->op2.constant = op2 - literals;
558+
559+
/* See GH-17733 and comment above. */
560+
if (opline->opcode == ZEND_INIT_FCALL) {
561+
Z_EXTRA_P(op2) = 0;
562+
ZEND_VM_SET_OPCODE_HANDLER(opline);
563+
}
545564
}
546565
#endif
547566
#if ZEND_USE_ABS_JMP_ADDR

0 commit comments

Comments
 (0)