|
php.net | support | documentation | report a bug | advanced search | search howto | statistics | random bug | login |
[2015-05-29 16:16 UTC] will dot o dot west at gmail dot com
Description:
------------
The following snippet is a minimal reproduction of an segv found in a WordPress site, wherein a theme was stashing data in an undeclared field of the WP_Query object, which has a __get but no __set. Its not clear whether this worked as intended in any prior versions of php.
Test script:
---------------
<?php
class wpq {
private $unreferenced;
public function __get($name) {
return $this->$name;
}
}
function ret_assoc() {
return array('foo' => 'bar');
}
$wpq = new wpq;
$wpq->interesting =& ret_assoc();
$x = $wpq->interesting;
printf("%s\n", $x);
Expected result:
----------------
likely printing an empty string
Actual result:
--------------
Segmentation fault: 11
PatchesPull RequestsHistoryAllCommentsChangesGit/SVN commits
|
|||||||||||||||||||||||||||
Copyright © 2001-2025 The PHP GroupAll rights reserved. |
Last updated: Thu Oct 30 22:00:01 2025 UTC |
hmm, it's not a stack overflow segfault.. it's a double free, freeing the op1 of ZEND_ASSIGN. a simple fix could be(but it break some tests, since they are not sharing one zval anymore): $ git diff diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index ac00c28..0eff680 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -896,13 +896,11 @@ static inline zval* zend_assign_to_variable(zval **variable_ptr_ptr, zval *value if (UNEXPECTED(variable_ptr == value)) { return variable_ptr; } else if (EXPECTED(!PZVAL_IS_REF(value))) { - Z_ADDREF_P(value); - *variable_ptr_ptr = value; - ZEND_ASSERT(variable_ptr != &EG(uninitialized_zval)); - GC_REMOVE_ZVAL_FROM_BUFFER(variable_ptr); - zval_dtor(variable_ptr); - efree(variable_ptr); - return value; + ZVAL_COPY_VALUE(&garbage, variable_ptr); + ZVAL_COPY_VALUE(variable_ptr, value); + zendi_zval_copy_ctor(*variable_ptr); + _zval_dtor_func(&garbage ZEND_FILE_LINE_CC); + return variable_ptr; } else { goto copy_value; }