php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #67539 ArrayIterator use-after-free due to object change during sorting
Submitted: 2014-06-29 15:31 UTC Modified: 2014-07-25 02:51 UTC
From: research at insighti dot org Assigned: laruence
Status: Closed Package: SPL related
PHP Version: Irrelevant OS: *
Private report: No CVE-ID: 2014-4698
 [2014-06-29 15:31 UTC] research at insighti dot org
Description:
------------
ArrayIterator should not be changed while being sorted.
There is a check missing in unserialize method in spl_array.c .



Test script:
---------------
<?php
$it = new ArrayIterator(array_fill(0,10,'X'), 1 );

function badsort($a, $b) {
        $GLOBALS['it']->unserialize($GLOBALS['it']->serialize());
        return TRUE;
}

$it->uksort('badsort');

Expected result:
----------------
Warning: Modification of ArrayObject during sorting is prohibited in spl_array.php on line 5

Actual result:
--------------
$ USE_ZEND_ALLOC=0 valgrind /opt/php/5.5.14/bin/php spl_array.php
==23209== Memcheck, a memory error detector
==23209== Copyright (C) 2002-2011, and GNU GPL'd, by Julian Seward et al.
==23209== Using Valgrind-3.7.0 and LibVEX; rerun with -h for copyright info
==23209== Command: /opt/php/5.5.14/bin/php spl_array.php
==23209==
==23209== Invalid read of size 4
==23209==    at 0x8374BAD: php_array_user_key_compare (array.c:736)
==23209==    by 0x849C8BC: zend_qsort_r (zend_qsort.c:84)
==23209==    by 0x849C9BE: zend_qsort (zend_qsort.c:123)
==23209==    by 0x8496368: zend_hash_sort (zend_hash.c:1463)
==23209==    by 0x837906B: zif_uksort (array.c:796)
==23209==    by 0x8479E7C: zend_call_function (zend_execute_API.c:955)
==23209==    by 0x6506747: ???
==23209==  Address 0x716c05c is 4 bytes inside a block of size 36 free'd
==23209==    at 0x402750C: free (vg_replace_malloc.c:427)
==23209==    by 0x8494B1A: zend_hash_destroy (zend_hash.c:565)
==23209==    by 0x84866E0: _zval_dtor_func (zend_variables.c:45)
==23209==    by 0x8477F47: _zval_ptr_dtor (zend_variables.h:35)
==23209==    by 0x8357D33: zim_spl_Array_unserialize (spl_array.c:1781)
==23209==    by 0x852E1B1: zend_do_fcall_common_helper_SPEC (zend_vm_execute.h:550)
==23209==    by 0x84F0935: execute_ex (zend_vm_execute.h:363)
==23209==    by 0x8479F14: zend_call_function (zend_execute_API.c:937)
==23209==    by 0x8374C11: php_array_user_key_compare (array.c:757)
==23209==    by 0x849C8BC: zend_qsort_r (zend_qsort.c:84)
==23209==    by 0x849C9BE: zend_qsort (zend_qsort.c:123)
==23209==    by 0x8496368: zend_hash_sort (zend_hash.c:1463)

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2014-06-29 15:35 UTC] research at insighti dot org
The following patch fixes the issue. Bug tracker does not allow us to submit a patch file to a private report for some reason.

diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c
index c38065f..a75f9ca 100644
--- a/ext/spl/spl_array.c
+++ b/ext/spl/spl_array.c
@@ -1737,6 +1737,12 @@ SPL_METHOD(Array, unserialize)
 {
 	spl_array_object *intern = (spl_array_object*)zend_object_store_get_object(getThis() TSRMLS_CC);

+	HashTable *htable = spl_array_get_hash_table(intern, 0 TSRMLS_CC);
+	if (htable->nApplyCount > 0) {
+		zend_error(E_WARNING, "Modification of ArrayObject during sorting is prohibited");
+		return;
+	}
+
 	char *buf;
 	int buf_len;
 	const unsigned char *p, *s;
 [2014-06-29 19:18 UTC] stas@php.net
-Type: Security +Type: Bug
 [2014-07-02 09:58 UTC] laruence@php.net
Automatic comment on behalf of laruence
Revision: http://git.php.net/?p=php-src.git;a=commit;h=22882a9d89712ff2b6ebc20a689a89452bba4dcd
Log: Fixed bug #67539 (ArrayIterator use-after-free due to object change during sorting)
 [2014-07-02 09:58 UTC] laruence@php.net
-Status: Open +Status: Closed
 [2014-07-03 22:45 UTC] research at insighti dot org
Please use CVE-2014-4698 for this issue.
 [2014-07-05 12:09 UTC] research at insighti dot org
As per the other reported bug, same applies for this one:

Please use CVE-2014-4698, the bug is in fact exploitable - not sure why was it made public before release of a patched version.

It's not remotely exploitable, however, shared environments relying on PHP security features (open_basedir, safe_mode in older PHPs, disable_functions and similar) are affected. We're ready to provide PoC is needed.
 [2014-07-07 15:22 UTC] dmitry@php.net
Automatic comment on behalf of laruence
Revision: http://git.php.net/?p=php-src.git;a=commit;h=22882a9d89712ff2b6ebc20a689a89452bba4dcd
Log: Fixed bug #67539 (ArrayIterator use-after-free due to object change during sorting)
 [2014-07-15 14:42 UTC] research at insighti dot org
-Status: Closed +Status: Assigned
 [2014-07-15 14:42 UTC] research at insighti dot org
Please use the assigned CVE-2014-4698. 5.5.15-RC1 is now out and CVE is missing.
 [2014-07-21 09:31 UTC] ab@php.net
Automatic comment on behalf of laruence
Revision: http://git.php.net/?p=php-src.git;a=commit;h=22882a9d89712ff2b6ebc20a689a89452bba4dcd
Log: Fixed bug #67539 (ArrayIterator use-after-free due to object change during sorting)
 [2014-07-21 09:31 UTC] ab@php.net
-Status: Assigned +Status: Closed
 [2014-07-21 10:02 UTC] ab@php.net
Automatic comment on behalf of laruence
Revision: http://git.php.net/?p=php-src.git;a=commit;h=22882a9d89712ff2b6ebc20a689a89452bba4dcd
Log: Fixed bug #67539 (ArrayIterator use-after-free due to object change during sorting)
 [2014-07-24 15:19 UTC] tyrael@php.net
-Assigned To: +Assigned To: laruence
 [2014-07-24 15:20 UTC] tyrael@php.net
-CVE-ID: +CVE-ID: 2014-4698
 [2014-07-25 05:59 UTC] stas@php.net
Automatic comment on behalf of laruence
Revision: http://git.php.net/?p=php-src.git;a=commit;h=51c38a09970c1f8395e68500c0b2ed1b3c9a6786
Log: Fixed bug #67539 (ArrayIterator use-after-free due to object change during sorting)
 [2014-07-30 09:52 UTC] tyrael@php.net
Automatic comment on behalf of laruence
Revision: http://git.php.net/?p=php-src.git;a=commit;h=51c38a09970c1f8395e68500c0b2ed1b3c9a6786
Log: Fixed bug #67539 (ArrayIterator use-after-free due to object change during sorting)
 [2014-07-30 09:52 UTC] tyrael@php.net
Automatic comment on behalf of laruence
Revision: http://git.php.net/?p=php-src.git;a=commit;h=22882a9d89712ff2b6ebc20a689a89452bba4dcd
Log: Fixed bug #67539 (ArrayIterator use-after-free due to object change during sorting)
 [2014-08-04 08:26 UTC] ab@php.net
Automatic comment on behalf of laruence
Revision: http://git.php.net/?p=php-src.git;a=commit;h=51c38a09970c1f8395e68500c0b2ed1b3c9a6786
Log: Fixed bug #67539 (ArrayIterator use-after-free due to object change during sorting)
 [2014-08-04 08:43 UTC] ab@php.net
Automatic comment on behalf of laruence
Revision: http://git.php.net/?p=php-src.git;a=commit;h=51c38a09970c1f8395e68500c0b2ed1b3c9a6786
Log: Fixed bug #67539 (ArrayIterator use-after-free due to object change during sorting)
 [2014-08-04 09:59 UTC] dmitry@php.net
Automatic comment on behalf of laruence
Revision: http://git.php.net/?p=php-src.git;a=commit;h=51c38a09970c1f8395e68500c0b2ed1b3c9a6786
Log: Fixed bug #67539 (ArrayIterator use-after-free due to object change during sorting)
 [2014-10-07 23:13 UTC] stas@php.net
Automatic comment on behalf of laruence
Revision: http://git.php.net/?p=php-src-security.git;a=commit;h=51c38a09970c1f8395e68500c0b2ed1b3c9a6786
Log: Fixed bug #67539 (ArrayIterator use-after-free due to object change during sorting)
 [2014-10-07 23:24 UTC] stas@php.net
Automatic comment on behalf of laruence
Revision: http://git.php.net/?p=php-src-security.git;a=commit;h=51c38a09970c1f8395e68500c0b2ed1b3c9a6786
Log: Fixed bug #67539 (ArrayIterator use-after-free due to object change during sorting)
 
PHP Copyright © 2001-2017 The PHP Group
All rights reserved.
Last updated: Sun Feb 26 14:01:37 2017 UTC