Skip to content

Fix use-after-free in zend_compile_const_decl() under opcache - #25302

Closed
nicolas-grekas wants to merge 1 commit into
php:PHP-8.4from
nicolas-grekas:fix-const-decl-uaf
Closed

nicolas-grekas wants to merge 1 commit into
php:PHP-8.4from
nicolas-grekas:fix-const-decl-uaf

Conversation

@nicolas-grekas

Copy link
Copy Markdown
Contributor

zend_compile_const_decl() interns the name of the constant, hands it to the literal of ZEND_DECLARE_CONST, then registers it as a seen symbol. With opcache, interning at runtime only finds strings already in shared memory: when the first call misses and another thread or process caches a script holding the same name before the literal interns it again, the literal swaps in the shared string and releases the original, which zend_register_seen_symbol() then reads and addrefs.

Registering the symbol first keeps the name referenced while the literal does that.

Found with FrankenPHP: restarting its workers makes them compile the same files concurrently on a fresh SHM. ASAN:

heap-use-after-free in zend_register_seen_symbol zend_compile.c:433, from zend_compile_const_decl :9484
freed by zend_string_release <- accel_new_interned_string_for_php <- zval_make_interned_string <- zend_insert_literal <- zend_emit_op <- zend_compile_const_decl :9482

No test: this is a race between threads.

@imfamousblack08-ctrl

Copy link
Copy Markdown

“Thanks for the fix — this looks like a real lifetime issue in zend_compile_const_decl() when OPcache interns the same constant name across threads. Registering the seen symbol before the literal interning step prevents the name from being released after shared-memory interning. The ASAN trace matches a use-after-free pattern.

@imfamousblack08-ctrl

Copy link
Copy Markdown

“Could an engine/OPcache maintainer review the lifetime/refcounting change here? The PR describes an ASAN use-after-free under concurrent compilation and notes there is no regression test because the bug is a race. A maintainer check on the ordering change would be helpful before merge.”

@LamentXU123 LamentXU123 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

/cc @ndossche

@ndossche ndossche left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Go ahead

LamentXU123 added a commit that referenced this pull request Nov 9, 2026
* PHP-8.6:
  Fix use-after-free in zend_compile_const_decl() under opcache (#25302)
LamentXU123 added a commit to LamentXU123/php-src that referenced this pull request Nov 9, 2026
* PHP-8.4:
  Fix use-after-free in zend_compile_const_decl() under opcache (php#25302)
LamentXU123 added a commit to LamentXU123/php-src that referenced this pull request Nov 9, 2026
* PHP-8.5:
  Fix use-after-free in zend_compile_const_decl() under opcache (php#25302)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants