1
0
mirror of https://github.com/php/php-src.git synced 2026-04-28 18:53:33 +02:00
Commit Graph

6659 Commits

Author SHA1 Message Date
Ilija Tovilo 2352cc1225 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Fix segfault in Tracing JIT with object reference (GH-20818)
2026-01-21 00:27:15 +01:00
Chris Hasiński 1db1c7f5c1 Fix segfault in Tracing JIT with object reference (GH-20818)
When FE_RESET_RW executes, it converts the CV to a reference before
checking if the array/object is empty. However, when the JIT creates
exit points for FE_RESET_RW in zend_jit_trace_handler(), it wasn't
updating the stack type for op1 to reflect this change.

This caused side traces compiled from these exit points to have
incorrect type information. The side trace's CV cleanup code would
see IS_OBJECT and generate a direct call to zend_objects_store_del(),
but the actual value was a zend_reference*, causing a segfault.

The fix adds ZEND_FE_RESET_RW to the list of opcodes that temporarily
set their op1 stack type to IS_UNKNOWN before creating exit points.
This follows the same pattern used for ZEND_BIND_INIT_STATIC_OR_JMP.
When IS_UNKNOWN, the JIT falls back to SSA type info which correctly
includes MAY_BE_REF for FE_RESET_RW's op1_def.

Fixes GH-20818
Closes GH-20948
2026-01-21 00:24:14 +01:00
Niels Dossche fd5e45116b Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Revert "Fix GH-20890: Segfault in zval_undefined_cv with non-simple property hook with minimal tracing JIT"
2026-01-20 21:05:50 +01:00
Niels Dossche 32c0245531 Revert "Fix GH-20890: Segfault in zval_undefined_cv with non-simple property hook with minimal tracing JIT"
This reverts commit 57c62eb2b3.
2026-01-20 21:05:26 +01:00
Niels Dossche 77c9c8c6c0 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Fix GH-20890: Segfault in zval_undefined_cv with non-simple property hook with minimal tracing JIT
2026-01-20 18:55:39 +01:00
Niels Dossche 57c62eb2b3 Fix GH-20890: Segfault in zval_undefined_cv with non-simple property hook with minimal tracing JIT
This is similar to f6c2e40a11 but for minimal JIT + tracing JIT.
Most of the times the tracing JIT shouldn't rely on going to the VM, but
in some cases, like in minimal JIT, it can and then it hits the same
bug.

Closes GH-20897.
2026-01-20 18:55:08 +01:00
Bob Weinand c878380065 Merge branch 'PHP-8.4' of github.com:php/php-src into PHP-8.5
* 'PHP-8.4' of github.com:php/php-src:
  Split the live-ranges of loop variables again (#20865)
2026-01-15 16:15:29 +01:00
Bob Weinand 27ed48c0be Split the live-ranges of loop variables again (#20865)
* Fix use-after-free in FE_FREE with GC interaction

When FE_FREE with ZEND_FREE_ON_RETURN frees the loop variable during
an early return from a foreach loop, the live range for the loop
variable was incorrectly extending past the FE_FREE to the normal
loop end. This caused GC to access the already-freed loop variable
when it ran after the RETURN opcode, resulting in use-after-free.

Fix by splitting the ZEND_LIVE_LOOP range when an FE_FREE with
ZEND_FREE_ON_RETURN is encountered:
- One range covers the early return path up to the FE_FREE
- A separate range covers the normal loop end FE_FREE
- Multiple early returns create multiple separate ranges

* Split the live-ranges of loop variables again

b0af9ac733 removed the live-range splitting of foreach variables, however it only added handling to ZEND_HANDLE_EXCEPTION.
This was sort-of elegant, until it was realized in 8258b7731b that it would leak the return variable, requiring some more special handling.
At some point we added live tmpvar rooting in 52cf7ab8a2, but this did not take into account already freed loop variables, which also might happen during ZEND_RETURN, which cannot be trivially accounted for, without even more complicated handling in zend_gc_*_tmpvars() functions.

This commit also proposes a simpler way of tracking the loop end in loopvar freeing ops: handle it directly during live range computation rather than during compilation, eliminating the need for opcache to handle it specifically.
Further, opcache was using live_ranges in its basic block computation in the past, which it no longer does. Thus this complication is no longer necessary and this approach should be actually simpler now.

Closes #20766.

Signed-off-by: Bob Weinand <bobwei9@hotmail.com>

---------

Signed-off-by: Bob Weinand <bobwei9@hotmail.com>
Co-authored-by: Gustavo Lopes <mail@geleia.net>
2026-01-15 16:13:43 +01:00
Niels Dossche c80ac797d4 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Add test for GH-20880 (#20919)
2026-01-12 22:45:43 +01:00
Niels Dossche 1052270001 Add test for GH-20880 (#20919)
Closes GH-20880.
2026-01-12 22:45:24 +01:00
Dmitry Stogov f7f0d228c2 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Update IR (#20916)
2026-01-12 21:23:52 +03:00
Dmitry Stogov 098b1f89bd Update IR (#20916)
IR commit: 40cd6ad28c376cf006c360f39d8aeff6d6e7bf78
2026-01-12 21:23:38 +03:00
Ilija Tovilo 918dc2355e Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Fix block_pass JMP[N]Z optimization
2026-01-11 14:56:05 +01:00
Ilija Tovilo f61b1fc036 Fix block_pass JMP[N]Z optimization
In the following optimization:

JMPZ(X,L1) JMP(L2) L1: -> JMPNZ(X,L2) NOP

L1 must not be followed by another block, so that it may safely be followed by
the block containing the JMPNZ. get_next_block() is used to verify L1 is the
direct follower. This function also skips empty blocks, including live, empty
target blocks, which will then implicitly follow the new follow block. This will
result in L1 being followed by two separate blocks, which is not possible.

Resolve this by get_next_block() stopping at target blocks.

Fixes OSS-Fuzz #472563272
Closes GH-20850
2026-01-11 14:55:23 +01:00
Dmitry Stogov 800c35027e Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Update IR (#20710)
2025-12-15 20:13:24 +03:00
Dmitry Stogov 886729454f Update IR (#20710)
IR commit: 3d72a7295c77743da22b36bab808ebb5f564488d
2025-12-15 20:13:03 +03:00
Linus Groh c24d51e59c opcache: Remove unused sys/ipc.h include from ZendAccelerator.c (#20662)
As far as I can tell that's been there since the initial open source
release (commit 528006a). The header defines ftok() and a handful of
IPC_* constants, none of which are used here.

System V IPC is increasingly being replaced by POSIX IPC and may
therefore not be implemented on new and/or hobbyist operating systems
such as SerenityOS[1]. In the past that wasn't an issue as the OPCache
could be disabled, which is no longer possible as of PHP 8.5[2].

I was able to build with the include patched out, but we would prefer
this to be addressed upstream.

1: https://github.com/SerenityOS/serenity/pull/26465
2: https://github.com/php/php-src/pull/18961
2025-12-08 18:45:06 +01:00
Arnaud Le Blanc 170fcf2381 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Remove CE cache from non-interned file cache strings
2025-11-06 11:21:45 +01:00
Arnaud Le Blanc 7e077f5a14 Merge branch 'PHP-8.3' into PHP-8.4
* PHP-8.3:
  Remove CE cache from non-interned file cache strings
2025-11-06 11:21:12 +01:00
Arnaud Le Blanc b062410d32 Remove CE cache from non-interned file cache strings
Strings loaded from the file cache can not have a CE cache, because their cache
slot is invalid. Remove the IS_STR_CLASS_NAME_MAP_PTR flag from these strings.
We can also avoid updating the str flags in SERIALIZE_STR(), since the same
updates must also be done in UNSERIALIZE_STR().

This was already done for interned strings, but not for non-interned ones.

Fixes GH-20329
Closes GH-20337
2025-11-06 11:20:17 +01:00
Ilija Tovilo ab0a9155d4 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Reset Z_EXTRA_P(op2) of ZEND_INIT_FCALL for opcache file cache
2025-10-31 17:50:42 +01:00
Ilija Tovilo 50c7f498b9 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 GH-17733
Closes GH-20328
2025-10-31 17:50:02 +01:00
Dmitry Stogov c31c697a85 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Update IR
2025-10-14 23:22:14 +03:00
Dmitry Stogov 191430dc3d Update IR
IR commit: 5a81104e650ebd7ac24eb63d4dff67db723a5278
2025-10-14 23:21:49 +03:00
Arnaud Le Blanc 0f634077aa Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Fix JIT TLS on MacOS
2025-10-13 16:31:14 +02:00
Arnaud Le Blanc 54d793dc41 Merge branch 'PHP-8.3' into PHP-8.4
* PHP-8.3:
  Fix JIT TLS on MacOS
2025-10-13 16:26:03 +02:00
Arnaud Le Blanc 3abebf3e31 Fix JIT TLS on MacOS
The dynamic loader, starting around version 1284, patches the thunk emitted for
thread local variables by the compiler, so that its format changes from

struct Thunk {
    void *func;
    size_t module;
    size_t offset;
}

to

struct Thunk_v2 {
     void *func;
     uint32_t module;
     uint32_t offset;
     // other fields
}

which has the same size, but not the same layout.

This is mentionned in
https://github.com/apple-oss-distributions/dyld/blob/9307719dd8dc9b385daa412b03cfceb897b2b398/libdyld/ThreadLocalVariables.h#L90

As a result, access to thread specific variables in JIT is broken.

Fix by using the new layout when the new dynamic loader is in use.

Closes GH-20121
2025-10-13 16:16:39 +02:00
Arnaud Le Blanc 01e34156a8 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Fix access to uninitialized variables in preload_load()
2025-10-10 15:45:22 +02:00
Arnaud Le Blanc 27807fd0f1 Merge branch 'PHP-8.3' into PHP-8.4
* PHP-8.3:
  Fix access to uninitialized variables in preload_load()
2025-10-10 15:44:33 +02:00
Arnaud Le Blanc ab9d121f48 Fix access to uninitialized variables in preload_load()
preload_load() reads EG(class_table) and EG(function_table), but these may not
be initialized. Move these accesses out of preload_load().

Closes GH-20081
2025-10-10 15:42:58 +02:00
Dmitry Stogov f77be081e1 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Update IR
2025-10-08 23:37:16 +03:00
Dmitry Stogov dd4189da83 Update IR
IR commit: 62d48607eb3ae5a9d1240115e9e4bdb3decdcadf
2025-10-08 23:36:58 +03:00
Arnaud Le Blanc 294e408ca2 Merge branch 'PHP-8.4' into PHP-8.5
* PHP-8.4:
  Fix race condition in zend_runtime_jit(), zend_jit_hot_func()
2025-10-07 10:53:53 +02:00
Arnaud Le Blanc 359ad80c4a Fix race condition in zend_runtime_jit(), zend_jit_hot_func()
zend_runtime_jit() prevents concurrent compilation with
zend_shared_alloc_lock(), but this doesn't prevent blocked threads from
trying to compile the function again after they acquire the lock.

In the case of GH-19889, one of the function entries is compiled with
zend_jit_handler(), which fails when the op handler has already been replaced by
a JIT'ed handler.

Fix by marking compiled functions with a new flag ZEND_FUNC_JITED, and
skipping compilation of marked functions. The same fix is applied to
zend_jit_hot_func().

Fixes GH-19889
Closes GH-19971
2025-10-07 10:48:44 +02:00
Ilija Tovilo faa4c7f9e6 Fix flaky gh19984.phpt test
When the parent finishes before the child, we may miss some output from the
child and have the test fail.
2025-10-03 22:25:18 +02:00
Ilija Tovilo bcd4be7d50 Fix double-free of EG(errors)/persistent_script->warnings on persist of already persisted file
Both processes race to compile warning_replay.inc. Whichever is first will get
to persist the script. The loser will use the script that is already persisted,
and the script that was just compiled is freed.

However, EG(errors) and persistent_script->warnings still refer to the same
allocation, and EG(errors) becomes a dangling pointer. To solve this, we simply
don't free warnings from free_persistent_script() anymore to maintain exclusive
ownership for EG(errors).

Furthermore, we need to adjust a call to zend_emit_recorded_errors() that would
previously use EG(errors), even when persistent_script has been swapped out.

Fixes GH-19984
Closes GH-19995
2025-09-30 22:53:25 +02:00
Gina Peter Banyard b4b0155f64 opcache: Fix segfault in function JIT due to NAN to bool warning (#19947) 2025-09-24 16:48:02 +01:00
Gina Peter Banyard 320fe2975b core: Warn when coercing NAN to other types
RFC: https://wiki.php.net/rfc/warnings-php-8-5#coercing_nan_to_other_types

Closes GH-19573
2025-09-23 11:16:51 +01:00
Gina Peter Banyard d27e1e1723 core: Add new test for coercions from NAN 2025-09-23 11:14:58 +01:00
Dmitry Stogov 83ccc97d80 Merge branch 'PHP-8.4'
* PHP-8.4:
  Update IR
2025-09-22 20:14:49 +03:00
Dmitry Stogov 1302b9f6da Update IR
IR commit: 425ca45ffed99b6d3085c6a7f7c9d4fb3c2b5737
2025-09-22 20:14:21 +03:00
Dmitry Stogov 58981ade34 Merge branch 'PHP-8.4'
* PHP-8.4:
  Update IR
2025-09-22 19:31:41 +03:00
Dmitry Stogov ef202cc4b7 Update IR
IR commit: 503018483d8333a3cfb25ab89a1eadefbee665bc
2025-09-22 19:31:06 +03:00
Arnaud Le Blanc f0878c8e30 Merge branch 'PHP-8.4'
* PHP-8.4:
  Handle references after FETCH_OBJ_R with REG destination
2025-09-22 17:57:35 +02:00
Arnaud Le Blanc 32c919b474 Handle references after FETCH_OBJ_R with REG destination
zend_jit_fetch_obj_r_slow_ex() may be used by the function JIT, which doesn't
rely on guards to handle references. Therefore it must deref the property value.

Other variants of zend_jit_fetch_obj_*_slow_ex can not be used used in function
JIT.

Fixes GH-19831
Closes GH-19838
2025-09-22 17:56:57 +02:00
Gina Peter Banyard b4ed215299 core: Warn when non-representable floats are coerced to int (#19760)
RFC: https://wiki.php.net/rfc/warnings-php-8-5#casting_out_of_range_floats_to_int
2025-09-21 23:53:16 +01:00
Niels Dossche 527ce267dd Merge branch 'PHP-8.4'
* PHP-8.4:
  Fix GH-19792: SCCP causes UAF for return value if both warning and exception are triggered
2025-09-11 19:37:29 +02:00
Niels Dossche 3026e88b0c Merge branch 'PHP-8.3' into PHP-8.4
* PHP-8.3:
  Fix GH-19792: SCCP causes UAF for return value if both warning and exception are triggered
2025-09-11 19:36:29 +02:00
Niels Dossche 2ad0b5cf05 Fix GH-19792: SCCP causes UAF for return value if both warning and exception are triggered
If an exception _and_ a warning (or deprecation) is emitted, then the
result is destroyed twice. Use an `else if` to prevent this.
This is tested via zend_test because the deprecation that triggered the
original reproducer may disappear in the future.

Closes GH-19793.
2025-09-11 19:35:53 +02:00
Arnaud Le Blanc 75945580bc Fix deoptimization after exit during inc/dec
When the assumption that (PRE|POST)_(INC|DEC) overflows turns out to be
false and we exit, effects are lost if op1 or result were in regs.

Fix by updating the stack map before creating the exit point.

Fixes GH-19669
Closes GH-19680
2025-09-11 12:35:39 +02:00