Skip to content

In ZTS, JIT code refers to zend_internal_function* that may not exist after the end of the request #10473

Closed
@dktapps

Description

@dktapps

Description

I don't have a reproducing test case for this with vanilla PHP yet. I encountered this while working on 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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions