You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
var_destroy() frees the var_hash back-reference extension chunks, then fires __destruct without taking BG(serialize_lock). A destructor that calls unserialize('R:NNNN;') with N beyond VAR_ENTRIES_MAX resolves against the freed chunks — use-after-free read.
This survives the 2026-10 security fixes (3584a98): confirmed on stock builds of 8.3.36 and 8.4.27 (independent research had ASAN-confirmed it on 8.5.12). No existing tracker found.
Reproducer (public PoC from the Chain-B research, runs as-is):
$ docker run --rm -v "$PWD":/x:ro -w /x php:8.3-cli php poc/verify_uaf_asan.php
PHP 8.3.36 (cli) (built: Oct 21 2026)
[*] __destruct fired (serialize_lock=0, BG(unserialize).level>0)
[*] R:1500 resolved to: integer
[+] UAF CONFIRMED: R:1500 read from freed memory!
$ docker run --rm -v "$PWD":/x:ro -w /x php:8.4-cli php poc/verify_uaf_asan.php # 8.4.27: same output
Possible fix location: take BG(serialize_lock) around the __destruct dispatch in var_destroy(), consistent with the guard used elsewhere for engine-driven destructor dispatch.
Aware of the SECURITY.md classification for malicious destructors / unserialize() inputs — filing as a public memory-safety bug per that policy; redirect me if you want it handled differently.
Credit: chain family discovered by ikow (Chain B); 8.5.12 ASAN verification by dinosn; stock 8.3.36/8.4.27 verification by me.
Closing as a duplicate of #24481 — my earlier searches for an existing tracker missed it, and #24481 (filed Oct 21, with an exploit in the report) covers this fully, including cross-branch stock-build confirmation (8.5.12 / 8.4.27 / 8.3.36 / 8.2.35 / 7.4.33, per the Valgrind confirmation in the thread) and the write-side analysis. Credit for the discovery belongs there; nothing further from my side.
Activity
srayuth089 commentedon Oct 25, 2026
Closing as a duplicate of #24481 — my earlier searches for an existing tracker missed it, and #24481 (filed Oct 21, with an exploit in the report) covers this fully, including cross-branch stock-build confirmation (8.5.12 / 8.4.27 / 8.3.36 / 8.2.35 / 7.4.33, per the Valgrind confirmation in the thread) and the write-side analysis. Credit for the discovery belongs there; nothing further from my side.