can induce segmentation fault with basic php code
| Bug #69732 | can induce segmentation fault with basic php code | ||||
|---|---|---|---|---|---|
| Submitted: | 2015-05-29 16:16 UTC | Modified: | 2015-05-31 11:10 UTC | ||
| From: | will dot o dot west at gmail dot com | Assigned: | dmitry (profile) | ||
| Status: | Closed | Package: | Reproducible crash | ||
| PHP Version: | 5.5.25 | OS: | OSX / Ubuntu Trusty | ||
| Private report: | No | CVE-ID: | None | ||
[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
Patches
Pull Requests
History
AllCommentsChangesGit/SVN commits
[2015-05-30 01:27 UTC] requinix@php.net
[2015-05-31 11:10 UTC] laruence@php.net
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; }[2015-06-01 09:22 UTC] dmitry@php.net
-Status: Assigned +Status: Closed