Sec Bug->Bug #74844 [Opn]: Type confusion when unserializing a crafted ArrayObject
| From: | stas@php.net | Date: | Sat, 12 Aug 2017 18:13:52 +0000 |
| Subject: | Sec Bug->Bug #74844 [Opn]: Type confusion when unserializing a crafted ArrayObject | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-210639@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=74844&edit=1
ID: 74844
Updated by: stas@php.net
Reported by: admin at stickman dot hu
Summary: Type confusion when unserializing a crafted
ArrayObject
Status: Open
-Type: Security
+Type: Bug
Package: SPL related
PHP Version: 7.1.6
Block user comment: N
Private report: Y
New Comment:
Thanks for the note, yes, this bug should be reclassified.
Please also note bug system is not a forum. If you want to discuss matters not pertaining to the
particular bugs, please use mailing lists or other venues.
Previous Comments:
------------------------------------------------------------------------
[2017-08-12 18:05:37] admin at stickman dot hu
I read that unserialize bugs are no longer considered security bugs.
Easy to "secure" your software by labeling everything "not security", very
professional, gg no re.
------------------------------------------------------------------------
[2017-07-02 16:11:18] admin at stickman dot hu
Description:
------------
This bug is related to #73029.
When ArrayObject gets unserialized, it checks for the unserialized internal "array"
variable to be either an array or an object. However, when it unserializes the additional
properties, the already unserialized array may still turn into a reference.
Then this internal array (now a reference) is cast to, and used as Z_OBJ, in
spl_array_get_hash_table_ptr, when the object is used.
The bug can be triggered both with a crafted serialized string, or simply serializing and
unserializing a crafted object, e.g. by putting it into $_SESSION, or shared memory.
It can also be triggered with a simple property read, if the ARRAY_AS_PROPS flags is set in a
crafted serialized string.
I think the error is both unserializing to a reference, and the absolutely unconditional
"else" in spl_array_get_hash_table_ptr.
- unserialize should make a defensive copy of 'array', like gmp does.
- spl_array_get_hash_table_ptr should check if the array field is actually an object.
Test script:
---------------
class A{};
$a = new A();
$ao = new ArrayObject($a);
$ao->reference_field = &$a;
$ao_corrupted = unserialize(serialize($ao));
$ao_corrupted['x'];
Expected result:
----------------
The code should not crash.
Actual result:
--------------
It throws segmentation fault with the following backtrace:
#0 rebuild_object_properties (zobj=0x7ffff6477078) at
/home/alex/projects/php/php-src/Zend/zend_object_handlers.c:80
#1 0x00000000004935be in spl_array_get_hash_table_ptr (intern=<optimized out>) at
/home/alex/projects/php/php-src/ext/spl/spl_array.c:100
#2 spl_array_get_hash_table (intern=<optimized out>) at
/home/alex/projects/php/php-src/ext/spl/spl_array.c:113
#3 spl_array_get_dimension_ptr (check_inherited=0, intern=<optimized out>,
offset=0x7ffff646f1c0, type=<optimized out>) at
/home/alex/projects/php/php-src/ext/spl/spl_array.c:296
#4 0x000000000048f56b in spl_array_read_dimension_ex (check_inherited=<optimized out>,
object=0x7ffff64140a0, offset=0x7ffff646f1c0, type=0, rv=0x7ffff6414180)
at /home/alex/projects/php/php-src/ext/spl/spl_array.c:430
#5 0x0000000000608fdb in zend_fetch_dimension_address_read (container=0x7ffff64140a0,
dim=0x7ffff646f1c0, dim_type=16, type=0, support_strings=1, slow=1, result=<optimized out>)
at /home/alex/projects/php/php-src/Zend/zend_execute.c:1880
#6 zend_fetch_dimension_address_read_R_slow (result=0x7ffff6414180, container=0x7ffff64140a0,
dim=<optimized out>) at /home/alex/projects/php/php-src/Zend/zend_execute.c:1909
#7 0x00000000005d11f7 in ZEND_FETCH_DIM_R_SPEC_CV_CONST_HANDLER (execute_data=0x7ffff6414030) at
/home/alex/projects/php/php-src/Zend/zend_vm_execute.h:38121
#8 0x00000000005b0338 in execute_ex (ex=0x7ffff6414030) at
/home/alex/projects/php/php-src/Zend/zend_vm_execute.h:432
#9 0x00000000005b05bb in zend_execute (op_array=0x7ffff6481000, return_value=<optimized out>)
at /home/alex/projects/php/php-src/Zend/zend_vm_execute.h:474
#10 0x000000000056e0a4 in zend_execute_scripts (type=8, retval=0x0, file_count=3) at
/home/alex/projects/php/php-src/Zend/zend.c:1476
#11 0x000000000050f72e in php_execute_script (primary_file=0x7fffffffcb60) at
/home/alex/projects/php/php-src/main/main.c:2537
#12 0x00000000006112e0 in do_cli (argc=2, argv=<optimized out>) at
/home/alex/projects/php/php-src/sapi/cli/php_cli.c:993
#13 0x00000000006104a6 in main (argc=2, argv=0xa04480) at
/home/alex/projects/php/php-src/sapi/cli/php_cli.c:1381
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=74844&edit=1