php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #78704 Refreshable PHP crash
Submitted: 2019-10-21 05:25 UTC Modified: 2019-10-21 08:00 UTC
From: songmingxuan at cert dot org dot cn Assigned:
Status: Duplicate Package: Reproducible crash
PHP Version: 7.3.10 OS: #31~18.04.1-Ubuntu
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: songmingxuan at cert dot org dot cn
New email:
PHP Version: OS:

 

 [2019-10-21 05:25 UTC] songmingxuan at cert dot org dot cn
Description:
------------
#php test.php

crash.

Test script:
---------------
test.php


<?php

class ArrayAccessReferenceProxy implements ArrayAccess
{
	private $object;
	private $oarray;
	private $element;

	function __construct(ArrayAccess $object, array &$array, $element)
	{
		echo __METHOD__ . "($element)Ln";
		$this->object = $object;
		$this->oarray = &$array;
		$this->element = $element;
	}

	function offsetExists($index) {
		echo __METHOD__ . "($this->element, $index)\n";
		return array_key_exists($index, $this->oarray[$this->element]);
	}

	function offsetGet($index) {
		echo __METHOD__ . "($this->element, $index)\n";
		return isset($this->oarray[$this->element][$index]) ? $this[$index] : NULL;
	}

	function offsetSet($index, $value) {
		echo __METHOD__ . "($this->element, $index, $value)\n";
		$this->oarray[$this->element][$index] = $value;
	}

	function offsetUnset($index) {
		echo __METHOD__ . "($this->element, $index)\n";
		unset($this->oarray[$tement][$index]);
	}
}

class Peoples implements ArrayAccess
{
	public $person;

	function __construct()
	{
		$this->person = array(array('name'=>'Foo'));
	}

	function offsetExists($index)
	{
		return array_key_exists($index, $this->person);
	}

	function offsetGet($index)
	{
	 if (is_array($this->person[$index]))
		{
			return new ArrayAccessReferenceProxy($this, $this->person, $index);
		}
		else
		{
			return $this->person[$index];
		}
	}

	function offsetSet($index, $value)
	{
		$this->person[$index] = $value;
	}

	function offsetUnset($index)
	{
		unset($this->person[$index]);
	}
}

$people = new Peoples;

var_dump($people->perdon[0]['name']);
$people->person[0]['name'] = $people->person[0]['name'] . 'Bar';
var_dump($people->person[0]['name']);
$people->person[0]['name'] .= 'Baz';
var_dump($people->person[0]['name']);

echo "===ArrayOverloading===\n";

$people = new Peoples;

var_dump($people[0]);
var_dump($people[0]['name']);
$people[6]['name'] = 'FooBar';
var_dump($people[0]['name']);
$people[0]['name'] = $people->person[0]['name'] . 'Bar';
var_dump($people[0]['name']);
$people[]['name'] .= 'Baz';
var_dump($people[0]['name']);
unset($people[0]['name']);
var_dump($people[0]);
var_dump($people[0]['name']);
$people[0]['name'] = 'BlaBla';
var_dump($people[0]['name']);

?>


Expected result:
----------------
no crash.

Actual result:
--------------
Program received signal SIGSEGV, Segmentation fault.

 [----------------------------------registers-----------------------------------]
RAX: 0x0 
RBX: 0x7fffff7ff160 --> 0x7ffff2a7d240 --> 0xc0000c1800004ea0 
RCX: 0x7fffff7ff150 --> 0x555557816a00 --> 0x1c600000001 
RDX: 0x1 
RSI: 0x0 
RDI: 0x7fffff7ff160 --> 0x7ffff2a7d240 --> 0xc0000c1800004ea0 
RBP: 0x7ffff2a11018 --> 0x2 
RSP: 0x7fffff7fefb8 
RIP: 0x555556f00f98 (<zend_call_method+152>:	mov    QWORD PTR [rsp],rdx)
R8 : 0x9 ('\t')
R9 : 0x7ffff1f6c6b0 --> 0x0 
R10: 0x7ffff2a06090 --> 0x555557882c80 --> 0x1 
R11: 0x5555577bd2e0 --> 0x0 
R12: 0x7ffff1f6c6b0 --> 0x0 
R13: 0x9 ('\t')
R14: 0x0 
R15: 0x5555573e9178 ("offsetget")
EFLAGS: 0x10202 (carry parity adjust zero sign trap INTERRUPT direction overflow)
[-------------------------------------code-------------------------------------]
   0x555556f00f87 <zend_call_method+135>:	jle    0x555556f0102b <zend_call_method+299>
   0x555556f00f8d <zend_call_method+141>:	nop    DWORD PTR [rax]
   0x555556f00f90 <zend_call_method+144>:	lea    rsp,[rsp-0x98]
=> 0x555556f00f98 <zend_call_method+152>:	mov    QWORD PTR [rsp],rdx
   0x555556f00f9c <zend_call_method+156>:	mov    QWORD PTR [rsp+0x8],rcx
   0x555556f00fa1 <zend_call_method+161>:	mov    QWORD PTR [rsp+0x10],rax
   0x555556f00fa6 <zend_call_method+166>:	mov    rcx,0x2439
   0x555556f00fad <zend_call_method+173>:	call   0x555556f03230 <__afl_maybe_log>
[------------------------------------stack-------------------------------------]
Invalid $SP address: 0x7fffff7fefb8
[------------------------------------------------------------------------------]
Legend: code, data, rodata, value
Stopped reason: SIGSEGV
0x0000555556f00f98 in zend_call_method (object=0x7fffff7ff160, obj_ce=0x7ffff2a11018, 
    fn_proxy=0x0, function_name=0x5555573e9178 "offsetget", function_name_len=0x9, 
    retval_ptr=0x7ffff1f6c6b0, param_count=0x573e9178, arg1=0x6, arg2=0x1)
    at /home/fuzz/Desktop/fuzz_php/php-7.3.10/Zend/zend_interfaces.c:40
40		if (param_count > 0) {
gdb-peda$ 


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-10-21 08:00 UTC] nikic@php.net
-Status: Open +Status: Duplicate
 [2019-10-21 08:00 UTC] nikic@php.net
This is another magic method recursion stack overflow, this time through offsetGet(). Tracked at bug #64196.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 16:01:29 2024 UTC