Sec Bug->Bug #73131 [Opn]: Use-after-free in php_var_serialize_intern
| From: | stas@php.net | Date: | Tue, 20 Sep 2016 17:39:23 +0000 |
| Subject: | Sec Bug->Bug #73131 [Opn]: Use-after-free in php_var_serialize_intern | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-204156@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=73131&edit=1
ID: 73131
Updated by: stas@php.net
Reported by: ahihibughunter at gmail dot com
Summary: Use-after-free in php_var_serialize_intern
Status: Open
-Type: Security
+Type: Bug
Package: Session related
Operating System: ALL
PHP Version: 5.6.26
Block user comment: N
Private report: Y
Previous Comments:
------------------------------------------------------------------------
[2016-09-20 17:23:50] ahihibughunter at gmail dot com
Description:
------------
static void php_var_serialize_intern(smart_str *buf, zval *struc, HashTable *var_hash TSRMLS_DC) /*
{{{ */
{
....
switch (Z_TYPE_P(struc)) {
...
case IS_ARRAY: {
...
if (Z_TYPE_PP(data) == IS_ARRAY) {
php_var_serialize_intern(buf, *data, var_hash TSRMLS_CC); <----------- call
php_var_serialize_intern again with new data
...
}
Free the memory when call to call_user_function_ex
static void php_var_serialize_intern(smart_str *buf, zval *struc, HashTable *var_hash TSRMLS_DC) /*
{{{ */
{
....
switch (Z_TYPE_P(struc)) {
....
case IS_OBJECT: {
....
if (ce && ce != PHP_IC_ENTRY && zend_hash_exists(&ce->function_table,
"__sleep", sizeof("__sleep"))) {
...
res = call_user_function_ex(CG(function_table), &struc, &fname, &retval_ptr, 0, 0, 1,
NULL TSRMLS_CC);
...
}
.....
.....
/php-src-PHP-5.6.26/Zend/zend_execute.h:80
efree_rel(zval_ptr); <------------------------ Free the memory
And memory reused
static void php_var_serialize_intern(smart_str *buf, zval *struc, HashTable *var_hash TSRMLS_DC) /*
{{{ */
{
...
case IS_OBJECT: {
...
if (res == SUCCESS) {
if (retval_ptr) {
if (HASH_OF(retval_ptr)) {
php_var_serialize_class(buf, struc, retval_ptr, var_hash TSRMLS_CC); <-----------------------
BOOM
...
}
Test script:
---------------
<?php
class Ahihi {};
class Ihaha
{
function __sleep()
{
new Ahihi;
$_SESSION['ihaha'] = "gogogo";
return array();
}
}
session_start();
$_SESSION['ihaha']['boom'] = new Ihaha;
?>
Expected result:
----------------
No crash
Actual result:
--------------
$ gdb php-src-PHP-5.6.26/sapi/cli/php
GNU gdb (Ubuntu 7.7.1-0ubuntu5~14.04.2) 7.7.1
..
(gdb) r crash.php
Starting program: /home/s/php/php-src-PHP-5.6.26/sapi/cli/php crash.php
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
Program received signal SIGSEGV, Segmentation fault.
0x0000000000927a21 in php_var_serialize_class_name (buf=0x7fffffffcd10, struc=0x7ffff7fc9e00)
at /home/s/php/php-src-PHP-5.6.26/ext/standard/var.c:607
607 PHP_SET_CLASS_ATTRIBUTES(struc);
(gdb) (gdb) print *struc
$1 = {value = {lval = 6510615555426900570, dval = 1.7838867517321418e+127, str = {
val = 0x5a5a5a5a5a5a5a5a <error: Cannot access memory at address 0x5a5a5a5a5a5a5a5a>,
len = 1515870810},
ht = 0x5a5a5a5a5a5a5a5a, obj = {handle = 1515870810, handlers = 0x5a5a5a5a5a5a5a5a}, ast =
0x5a5a5a5a5a5a5a5a},
refcount__gc = 1515870810, type = 90 'Z', is_ref__gc = 90 'Z'}
gdb) bt
#0 0x0000000000927a21 in php_var_serialize_class_name (buf=0x7fffffffcd10, struc=0x7ffff7fc9e00)
at /home/s/php/php-src-PHP-5.6.26/ext/standard/var.c:607
#1 0x00000000009283bf in php_var_serialize_class (buf=0x7fffffffcd10, struc=0x7ffff7fc9e00,
retval_ptr=0x7ffff7fcb678, var_hash=0x7ffff7fcb0f8) at
/home/s/php/php-src-PHP-5.6.26/ext/standard/var.c:623
#2 0x000000000092c1c1 in php_var_serialize_intern (buf=0x7fffffffcd10, struc=0x7ffff7fc9e00,
var_hash=0x7ffff7fcb0f8)
at /home/s/php/php-src-PHP-5.6.26/ext/standard/var.c:813
#3 0x000000000092cd72 in php_var_serialize_intern (buf=0x7fffffffcd10, struc=0x7ffff7fccf90,
var_hash=0x7ffff7fcb0f8)
at /home/s/php/php-src-PHP-5.6.26/ext/standard/var.c:886
#4 0x000000000092d0cd in php_var_serialize (buf=0x7fffffffcd10, struc=0x7ffff7fcea08,
var_hash=0x7fffffffccd0)
at /home/s/php/php-src-PHP-5.6.26/ext/standard/var.c:905
#5 0x00000000007fc8b6 in ps_srlzr_encode_php (newstr=0x7fffffffcd68, newlen=0x7fffffffcd80)
at /home/s/php/php-src-PHP-5.6.26/ext/session/session.c:988
#6 0x00000000007f9a73 in php_session_encode (newlen=0x7fffffffcd80)
at /home/s/php/php-src-PHP-5.6.26/ext/session/session.c:209
#7 0x00000000007fa72d in php_session_save_current_state () at
/home/s/php/php-src-PHP-5.6.26/ext/session/session.c:542
#8 0x000000000080041a in php_session_flush () at
/home/s/php/php-src-PHP-5.6.26/ext/session/session.c:1646
#9 0x00000000008027ff in zm_deactivate_session (type=1, module_number=28)
at /home/s/php/php-src-PHP-5.6.26/ext/session/session.c:2415
#10 0x0000000000ab451f in zend_deactivate_modules () at
/home/s/php/php-src-PHP-5.6.26/Zend/zend_API.c:2488
#11 0x0000000000a0e158 in php_request_shutdown (dummy=0x0) at
/home/s/php/php-src-PHP-5.6.26/main/main.c:1867
#12 0x0000000000b5f4af in do_cli (argc=2, argv=0x1457a20) at
/home/s/php/php-src-PHP-5.6.26/sapi/cli/php_cli.c:1177
#13 0x0000000000b5fd39 in main (argc=2, argv=0x1457a20) at
/home/s/php/php-src-PHP-5.6.26/sapi/cli/php_cli.c:1378
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=73131&edit=1