[php-src] Issue #10473: In ZTS, JIT code refers to zend_internal_function* that may not exist after the end of the request
| From: | dktapps | Date: | Mon, 30 Jan 2023 16:02:04 +0000 |
| Subject: | [php-src] Issue #10473: In ZTS, JIT code refers to zend_internal_function* that may not exist after the end of the request | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-243595@lists.php.net to get a copy of this message | ||
Issue: https://github.com/php/php-src/issues/10473
Author: dktapps
### Description
I don't have a reproducing test case for this with vanilla PHP yet. I encountered this while
working on [pmmp/pthreads](https://github.com/pmmp/pthreads).
In ZTS, internal functions are duplicated here: https://github.com/php/php-src/blob/PHP-8.0/Zend/zend.c#L665
and at the end of the request, they are freed here: https://github.com/php/php-src/blob/PHP-8.0/Zend/zend.c#L701
This means that when compiling functions on a particular thread, any
zend_internal_function referenced are actually specific to that thread.
If this jitted code is subsequently referenced from OPcache by another thread/request, a UAF may
occur if the caller has some reason to access the zend_function from the call stack (I ran into this
with a closure calling var_dump() - UAF occurred because var_dump() wanted
to get the current filename and ran across a freed zend_internal_function from another
thread).
This appears not to reproduce on Windows, since ASLR prevents referring directly to function
addresses anyway, so the JIT already has alternative measures for that.
It would appear that the solution to this would be to just not use const addresses in JIT code on
ZTS. It's already doing this for Windows anyway because of ASLR.
### PHP Version
8.0.27 (ZTS)
### Operating System
WSL2 Ubuntu 20.04