Skip to content

Fix GH-22060: UAF in class-autoloader dispatch on self-unregister#22085

Open
iliaal wants to merge 1 commit into
php:masterfrom
iliaal:fix/gh-22060-autoload-uaf
Open

Fix GH-22060: UAF in class-autoloader dispatch on self-unregister#22085
iliaal wants to merge 1 commit into
php:masterfrom
iliaal:fix/gh-22060-autoload-uaf

Conversation

@iliaal
Copy link
Copy Markdown
Contributor

@iliaal iliaal commented May 19, 2026

A method-bound autoloader registered as [$obj, 'load'] can call spl_autoload_unregister([$this, 'load']) from inside its own callback. The hash entry's destructor releases the last ref on the object, frees it, and the rest of the PHP body (e.g. echo $this->data) reads freed memory. The dispatch loop in zend_perform_class_autoload calls zend_call_known_fcc(func_info, ...), but zend_call_function reads fci_cache->object into EX(This) without bumping the refcount; the call convention is that the caller holds the ref, and here the only ref was the hash entry's.

Fix pins object and closure across the call with GC_ADDREF/OBJ_RELEASE. The pointers are saved locally before the call so the releases work even when func_info itself is freed mid-call by self-unregister.

zend_perform_class_autoload walked the autoloader hashtable and called
zend_call_known_fcc on each FCC without pinning its refcounted owners.
When the autoloader's PHP body called spl_autoload_unregister([$this,
'load']), the hash bucket destructor released the last ref on $this
and freed it mid-call; the subsequent $this->data read landed in
freed memory.

Pin object and closure manually around the call. Don't use
zend_fcc_dup/zend_fcc_dtor: zend_fcc_dtor frees trampoline storage
based on ZEND_ACC_CALL_VIA_TRAMPOLINE, which would double-free the
hash entry's trampoline copy for __call-based autoloaders.

Fixes phpGH-22060
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.

1 participant