opcache: smm_shared_globals left pointing to a dead stack frame when there is no SHM backend
Les mainteneurs répondent en général sous 1 jour
Personne n'a encore pris cette issue.
Évaluation
- Difficulté
- 2/5
- Temps estimé
- 1-3 heures
- Accessibilité débutants
- 72/100
- Type d'issue
- Bug
- Clarté
- Clairement spécifiée
- Activité
- Active
- Domaine
- backend, performance
Piste de recherche
Commencez dans ext/opcache/zend_shared_alloc.c, au niveau de zend_shared_alloc_startup(), en vous concentrant sur le retour anticipé lorsque handler_table == NULL et sur la façon dont les autres retours anticipés réinitialisent smm_shared_globals. Reproduisez l’échec avec le programme embed SAPI fourni et la configuration AddressSanitizer, ou examinez les chemins de démarrage existants. Le travail est terminé lorsque le chemin sans SHM ne laisse plus de pointeur vers la variable locale sur la pile et que le reproducteur se termine sans signaler d’utilisation de la pile après le retour.
Rédigé par le modèle d'indexation à partir du texte de l'issue.
Description
Description
When opcache has no shared memory backend (handler_table is empty), zend_shared_alloc_startup() returns NO_SHM_BACKEND with smm_shared_globals still pointing to its local tmp_shared_globals. The other early returns (FAILED_REATTACHED, ALLOC_FALLBACK) reset it to NULL; this one does not.
Nothing reads it while opcache is disabled. But if the engine is started again in the same process (embed SAPI: php_embed_init() / php_embed_shutdown()), with opcache.file_cache_only=1, zend_shared_alloc_startup() is not called. zend_accel_in_shm() then reads ZSMMG(shared_segments_count) and ZSMMG(shared_segments) from that dead frame, and zend_persist uses its answer to decide what is already persisted.
We hit it with PHP compiled to WebAssembly (emscripten), which has no SHM backend, as a memory corruption ("memory access out of bounds") when opcache later compiled some files to its file cache. Here is a native reproducer, with the SHM backends disabled at configure time:
php_cv_shm_ipc=no php_cv_shm_mmap_anon=no php_cv_shm_mmap_posix=no \
./configure --enable-embed --disable-all --disable-opcache-jit --enable-address-sanitizer
make && make install
gcc -fsanitize=address repro.c -o repro $(php-config --includes) -L/usr/local/lib -lphp
mkdir /tmp/opcache
USE_ZEND_ALLOC=0 ASAN_OPTIONS=detect_leaks=0:detect_stack_use_after_return=1 ./repro
repro.c:
#include <sapi/embed/php_embed.h>
#include <stdlib.h>
static void start(const char *phprc, const char *code)
{
setenv("PHPRC", phprc, 1);
php_embed_init(0, NULL);
zend_first_try {
zend_eval_string((char *) code, NULL, "repro");
} zend_end_try();
php_embed_shutdown();
}
int main(void)
{
start("/repro/first", "var_dump(opcache_get_status(false));");
start("/repro/second", "var_dump(opcache_compile_file('/repro/script.php'));");
return 0;
}
/repro/first/php.ini:
opcache.enable=1
opcache.log_verbosity_level=4
/repro/second/php.ini:
opcache.enable=1
opcache.file_cache=/tmp/opcache
opcache.file_cache_only=1
/repro/script.php:
<?php
const PRIMES = [2, 3, 5, 7];
function primes(): array
{
static $calls = [];
$calls[] = true;
return PRIMES;
}
Resulted in this output:
Message Opcode Caching is disabled: No available SHM backend. Set opcache.enable=0 to hide this message.
bool(false)
==1==ERROR: AddressSanitizer: stack-use-after-return on address 0x7f1327702a38 at pc 0x7f1329e77995 bp 0x7ffe0f741820 sp 0x7ffe0f741818
READ of size 4 at 0x7f1327702a38 thread T0
#0 0x7f1329e77994 in zend_accel_in_shm /php-src/ext/opcache/zend_shared_alloc.c:701
#1 0x7f1329e598f4 in zend_persist_op_array_calc_ex /php-src/ext/opcache/zend_persist_calc.c:244
#2 0x7f1329e61c73 in zend_accel_script_persist_calc /php-src/ext/opcache/zend_persist_calc.c:665
#3 0x7f1329e797c2 in store_script_in_file_cache /php-src/ext/opcache/ZendAccelerator.c:1520
#4 0x7f1329e8da01 in cache_script_in_file_cache /php-src/ext/opcache/ZendAccelerator.c:1571
#5 0x7f1329e8da01 in file_cache_compile_file /php-src/ext/opcache/ZendAccelerator.c:1962
#6 0x7f1329e9396d in persistent_compile_file /php-src/ext/opcache/ZendAccelerator.c:2017
#7 0x7f1329e3e564 in zif_opcache_compile_file /php-src/ext/opcache/zend_accelerator_module.c:1013
Address 0x7f1327702a38 is located in stack of thread T0 at offset 56 in frame
#0 0x7f1329e75c2f in zend_shared_alloc_startup /php-src/ext/opcache/zend_shared_alloc.c:185
This frame has 1 object(s):
[48, 128) 'tmp_shared_globals' (line 188) <== Memory access at offset 56 is inside this variable
But I expected this output instead:
Message Opcode Caching is disabled: No available SHM backend. Set opcache.enable=0 to hide this message.
bool(false)
bool(true)
Resetting it before that return gives the expected output, with no ASan report:
if (handler_table->name == NULL) {
+ smm_shared_globals = NULL;
return NO_SHM_BACKEND;
}
I can open a PR with this fix.
PHP Version
PHP 8.5.12, and master (d15160d5)
Operating System
Debian trixie, x86_64, gcc 14.2 (ASan). First seen with emscripten 6.0.13 (WebAssembly).
- Langage dominant
- C
- Étoiles
- 41.7k
- Forks
- 8.5k
- Merge moyen
- 2 j 18 h
- PR mergées (30 j)
- 145
Préparer son environnement
- Aucun Dockerfile ni fichier Docker Compose
- Aucun modèle de pull request
- Lire le guide de contribution
Par où commencer
- Lisez l'issue en entier, puis le guide de contribution du projet.
- Signalez en commentaire que vous la prenez — cela évite que deux personnes fassent le même travail.
- Forkez le dépôt et travaillez sur une branche.
- Ouvrez une pull request qui référence le numéro de l'issue.
Autres issues de php/php-src
-
SNMP accepts malformed remote portsPeut-être pris Une pull request liée à cette issue est ouverte ou déjà fusionnée. Ouverte
Difficulté 2/5 Une demi-journée Accessibilité débutants 62/100
php/php-src#25137 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour
-
Bug Status: Needs Triage
Difficulté 2/5 1-3 heures Accessibilité débutants 64/100
Les mainteneurs répondent en général sous 1 jour
-
quoted_printable_encode() produces lines longer than 76 characters for bytes 0xF5 to 0xFFPeut-être pris Une pull request liée à cette issue est ouverte ou déjà fusionnée. Ouverte
Difficulté 2/5 1-3 heures Accessibilité débutants 76/100
Les mainteneurs répondent en général sous 1 jour
-
Bug Status: Needs Triage
Difficulté 2/5 1-3 heures Accessibilité débutants 62/100
php/php-src#24196 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour
-
Feature Status: Needs Triage
Difficulté 2/5 1-3 heures Accessibilité débutants 73/100
php/php-src#24183 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour
Toutes les issues de php/php-src
Issues similaires
-
[compiler-rt] Rtsan-aarch64-NoInstTest: error: no such file or directory: 'NOTFOUND' (libatomic)Ouvertebuild-problem compiler-rt:rtsan platform:linux
Difficulté 2/5 1-3 heures Accessibilité débutants 63/100
llvm/llvm-project#239039 ·
Les mainteneurs répondent en général sous 1 jour
-
component:obi contribfest go test
Difficulté 2/5 Moins d'une heure Accessibilité débutants 83/100
open-telemetry/opentelemetry-ebpf-instrumentation#4143 · 1 commentaire ·
Les mainteneurs répondent en général sous 1 jour
-
Bug :bug:
Difficulté 2/5 1-3 heures Accessibilité débutants 72/100
sonic-net/sonic-buildimage#30541 ·
Les mainteneurs répondent en général sous 1 jour