Skip to content

Use after free with weakmaps dependent on destruction order #18833

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
danog opened this issue Jun 11, 2025 · 0 comments · May be fixed by #18834
Open

Use after free with weakmaps dependent on destruction order #18833

danog opened this issue Jun 11, 2025 · 0 comments · May be fixed by #18834

Comments

@danog
Copy link
Contributor

danog commented Jun 11, 2025

Description

The following code:

<?php

class a {
    public static WeakMap $map;
    public static Generator $storage;
}

a::$map = new WeakMap;

$closure = function () {
    $obj = new a;
    a::$map[$obj] = true;
    yield $obj;
};
a::$storage = $closure();
a::$storage->current();

Causes a use after free, due to the following destruction order in zend_objects_store_free_object_storage:

1. a
2. Generator
3. Closure
4. WeakMap

At 1, obj->handlers->free_obj is actually never invoked for a and only the flag is set, because normally we're in the fast fast_shutdown path, which skips invoking free_obj for standard PHP objects (thus, the weak map is not notified).
At 2, the zend_generator_free_storage procedure causes a to be actually freed with efree, since it is only referenced by the generator, which is being freed; thus, a is actually freed without ever notifying the weak map.
At 4, the weak map accesses the already freed object while iterating over the members.

The issue was particularly nasty to reproduce as it won't reproduce by just disabling the zend allocator and enabling ASAN, as the fast shutdown path is for some reason disabled when using custom allocators (will submit a PR to fix that on ASAN).

phpredis/phpredis#2630 is a direct consequence of this bug.

Submitting a PR with a fix, and another PR with misc related improvements.

PHP Version

PHP 8.3.22+

Operating System

No response

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants