From 359ad80c4a9f469956e303138c26ac46bb54a25f Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Fri, 26 Sep 2025 10:24:45 +0200 Subject: [PATCH 1/2] 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 --- NEWS | 2 ++ Zend/Optimizer/zend_func_info.h | 2 +- ext/opcache/jit/zend_jit.c | 12 ++++++++---- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/NEWS b/NEWS index 1d8270a3b8751..9eadaaf7f3d9c 100644 --- a/NEWS +++ b/NEWS @@ -44,6 +44,8 @@ PHP NEWS . Fixed bug GH-19669 (assertion failure in zend_jit_trace_type_to_info_ex). (Arnaud) . Fixed bug GH-19831 (function JIT may not deref property value). (Arnaud) + . Fixed bug GH-19889 (race condition in zend_runtime_jit(), + zend_jit_hot_func()). (Arnaud) - Phar: . Fix memory leak and invalid continuation after tar header writing fails. diff --git a/Zend/Optimizer/zend_func_info.h b/Zend/Optimizer/zend_func_info.h index b53683bdf5e70..db00d843ee10e 100644 --- a/Zend/Optimizer/zend_func_info.h +++ b/Zend/Optimizer/zend_func_info.h @@ -39,7 +39,7 @@ #define ZEND_FUNC_JIT_ON_PROF_REQUEST (1<<14) /* used by JIT */ #define ZEND_FUNC_JIT_ON_HOT_COUNTERS (1<<15) /* used by JIT */ #define ZEND_FUNC_JIT_ON_HOT_TRACE (1<<16) /* used by JIT */ - +#define ZEND_FUNC_JITED (1<<17) /* used by JIT */ typedef struct _zend_func_info zend_func_info; typedef struct _zend_call_info zend_call_info; diff --git a/ext/opcache/jit/zend_jit.c b/ext/opcache/jit/zend_jit.c index b0423dc06bd1e..19e5520b1569e 100644 --- a/ext/opcache/jit/zend_jit.c +++ b/ext/opcache/jit/zend_jit.c @@ -2945,8 +2945,9 @@ static int ZEND_FASTCALL zend_runtime_jit(void) bool do_bailout = 0; zend_shared_alloc_lock(); + jit_extension = (zend_jit_op_array_extension*)ZEND_FUNC_INFO(op_array); - if (ZEND_FUNC_INFO(op_array)) { + if (jit_extension && !(jit_extension->func_info.flags & ZEND_FUNC_JITED)) { SHM_UNPROTECT(); zend_jit_unprotect(); @@ -2958,11 +2959,12 @@ static int ZEND_FASTCALL zend_runtime_jit(void) opline++; } } - jit_extension = (zend_jit_op_array_extension*)ZEND_FUNC_INFO(op_array); - opline->handler = jit_extension->orig_handler; + ((zend_op*)opline)->handler = jit_extension->orig_handler; /* perform real JIT for this function */ zend_real_jit_func(op_array, NULL, NULL, ZEND_JIT_ON_FIRST_EXEC); + + jit_extension->func_info.flags |= ZEND_FUNC_JITED; } zend_catch { do_bailout = true; } zend_end_try(); @@ -3024,7 +3026,7 @@ void ZEND_FASTCALL zend_jit_hot_func(zend_execute_data *execute_data, const zend zend_shared_alloc_lock(); jit_extension = (zend_jit_op_array_hot_extension*)ZEND_FUNC_INFO(op_array); - if (jit_extension) { + if (jit_extension && !(jit_extension->func_info.flags & ZEND_FUNC_JITED)) { SHM_UNPROTECT(); zend_jit_unprotect(); @@ -3039,6 +3041,8 @@ void ZEND_FASTCALL zend_jit_hot_func(zend_execute_data *execute_data, const zend /* perform real JIT for this function */ zend_real_jit_func(op_array, NULL, opline, ZEND_JIT_ON_HOT_COUNTERS); + + jit_extension->func_info.flags |= ZEND_FUNC_JITED; } zend_catch { do_bailout = 1; } zend_end_try(); From 66708de8417d743aba4f542ee6476b646cdb918b Mon Sep 17 00:00:00 2001 From: Arnaud Le Blanc Date: Thu, 2 Oct 2025 15:53:53 +0200 Subject: [PATCH 2/2] Upgrade Alpine in nightly job Closes GH-20044 --- .github/workflows/nightly.yml | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index a8c8c80d7d500..e0322e3b1be2e 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -93,9 +93,9 @@ jobs: ALPINE: if: inputs.run_alpine name: ALPINE_X64_ASAN_UBSAN_DEBUG_ZTS - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 container: - image: 'alpine:3.20.1' + image: 'alpine:3.22' steps: - name: git checkout uses: actions/checkout@v5 @@ -103,11 +103,6 @@ jobs: ref: ${{ inputs.branch }} - name: apk uses: ./.github/actions/apk - - name: LLVM 17 (ASAN-only) - # libclang_rt.asan-x86_64.a is provided by compiler-rt, and only for clang17: - # https://pkgs.alpinelinux.org/contents?file=libclang_rt.asan-x86_64.a&path=&name=&branch=v3.20 - run: | - apk add clang17 compiler-rt - name: System info run: | echo "::group::Show host CPU info" @@ -122,8 +117,8 @@ jobs: configurationParameters: >- CFLAGS="-fsanitize=undefined,address -fno-sanitize=function -DZEND_TRACK_ARENA_ALLOC" LDFLAGS="-fsanitize=undefined,address -fno-sanitize=function" - CC=clang-17 - CXX=clang++-17 + CC=clang-20 + CXX=clang++-20 --enable-debug --enable-zts skipSlow: true # FIXME: This should likely include slow extensions