-
Notifications
You must be signed in to change notification settings - Fork 7.8k
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
Corrupted memory in destructor with weak references #13612
Comments
Reduced further: <?php
class WeakAnalysingMapRepro
{
public array $valueWithOwnerCountByIndex = [];
private array $ownerDestructorHandlers = [];
public function __construct()
{
$handler = new class($this) {
private \WeakReference $weakAnalysingMap;
public function __construct(WeakAnalysingMapRepro $analysingMap)
{
$this->weakAnalysingMap = \WeakReference::create($analysingMap);
}
public function __destruct()
{
var_dump($this->weakAnalysingMap->get());
}
public function addReference($index): void
{
$analysingMap = $this->weakAnalysingMap->get();
$analysingMap->valueWithOwnerCountByIndex[$index] = true;
}
};
$this->ownerDestructorHandlers[] = $handler;
$handler->addReference(10);
}
}
new WeakAnalysingMapRepro(); Results in a reliably reproducible UAF with ASAN. EDIT: it seems the destruction of the outer object already started, resulting in a failure when var_dumping because it tries to print out freed arrays. |
Inside |
Inside `zend_object_std_dtor` the weakrefs are notified after the destruction of properties already took place. In this test case, the destructor of an anon class will be invoked due to the property destruction. That class has a weak reference to its parent. This means that the destructor can access parent properties that already have been destroyed, resulting in a UAF. Fix this by notifying the weakrefs at the start of the object's destruction.
Sure, I highly reduced the code... the test in #13613 seems correct. Thank you for looking into this issue so blazingly quickly! One question - can this be classified as security issue, it the fix be landed to lower branches than 8.2? |
I don't think it qualifies as a security issue as it doesn't seem to fit the attack model from https://github.com/php/policies/blob/main/security-classification.rst |
Isn't UAF - which can hold any data - a security issue? In theory, UAF can leak sensitive data or be used to corrupt some persistent data like file or database. Also, according to the linked document only high and medium security issues are usually assigned a CVE and IMO this issue could have CVE report. |
@mvorisek Whether something is a security issue depends on the remote exploitability. This isn't exploitable without carefully crafted PHP code, i.e. nothing remote attackers can control. |
I was able to workaround around this issue by creating a property in the partly-destructed object and weakly referencing it - the property seems to be guaranteed to be freed - https://3v4l.org/nUMJD. It seems it is not possible to fix this issue (from user code) without modifying the weakly referenced object (as we cannot tell if the weakly referenced object started the destruction process or not). About the security classification, based on the linked document, it can:
Of couse, we can disagree on this, but is there anything againts not landing the fix into at least PHP 8.1, can we ask the release managers for their approval? |
I'll give a bit more explanation about the policy. First, I agree that a UAF is bad: it can indeed cause data corruption or access data structures that should've already been destroyed.
You'll have to ping and convince the RMs to do so. I mean, I get it. This is an annoying bug that affects you and PHP 8.1 will still be around for a while, whilst not getting a fix. But that's just the policy. The question also is: if this gets an exception, for an extra 8.1 release, what other bugs should get an exception as well? |
* PHP-8.2: [ci skip] NEWS Fix GH-13612: Corrupted memory in destructor with weak references
* PHP-8.3: [ci skip] NEWS Fix GH-13612: Corrupted memory in destructor with weak references
Hi , @ramsey and @patrickallaert, PHP 8.1 RMs, would you approve this to be landed/fixed in PHP 8.1? The fix is simple - 39b8d5c871. As analysed in #13612 (comment) the issue has no easy workaround and in theory, it might cause unwated data to be stored and/or sensitive data leaked. |
I agree with @nielsdos's assessment that this isn't a security bug, so we shouldn't update 8.1 because it opens the door to questions about other types of bugs to merge into 8.1. |
…3612 Usage of driver throw an error on Election object destruction..
…3612 + php/php-src#13613 Usage of driver throw an error on Election object destruction..
Description
In the code below,
var_dump(array_keys($analysingMap->valueWithOwnerCountByIndex))
called twice prints different results even if the value is not changed between the calls.I did my best to create a minimal repro. It seems the issue is present when weak references and destructor is used.
When opcache and/or GC is disabled, the issue is still present. It seems there is some allocation/refcounting issue in destructors.
repro: https://3v4l.org/h7ZER
Resulted in this output:
But I expected this output instead:
PHP Version
any (tested 7.4, 8.1, 8.3, master)
Operating System
any (tested Windows, Linux)
The text was updated successfully, but these errors were encountered: