Skip to content

Fix use-after-free in json_encode() of a JsonSerializable object#22470

Open
iliaal wants to merge 1 commit into
php:PHP-8.4from
iliaal:fix/json-jsonserialize-uaf-84
Open

Fix use-after-free in json_encode() of a JsonSerializable object#22470
iliaal wants to merge 1 commit into
php:PHP-8.4from
iliaal:fix/json-jsonserialize-uaf-84

Conversation

@iliaal

@iliaal iliaal commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

php_json_encode_serializable_object() keeps the object pointer and its recursion guard live across the jsonSerialize() call. An error handler invoked during that call can drop the object's last reference through an aliased array element, leaving the post-call recursion-guard clear and the return-value identity check reading freed memory. Pin the object across the call. The 8.5 and master encoder dispatches through zend_call_known_function() and gets the same fix in php-src#22469.

php_json_encode_serializable_object() holds a raw pointer to the object and
its recursion guard across the jsonSerialize() call. A user error handler
invoked during that call can drop the object's last reference, leaving the
post-call recursion-guard clear and the return-value identity check reading
freed memory. Pin the object across the call.

@Girgias Girgias 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.

We don't backport these sorts of fuzzer bugs

<?php
class Bar implements JsonSerializable {
public function jsonSerialize(): mixed {
echo $undefined;

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.

Ditto as the other PR: just use trigger_error function

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.

2 participants