Skip to content

Instantly share code, notes, and snippets.

@smalyshev
Created August 2, 2015 04:46

Revisions

  1. smalyshev created this gist Aug 2, 2015.
    69 changes: 69 additions & 0 deletions 70166.diff
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,69 @@
    commit ca594eda0cc7da6f10a624496a21f49b9ce10283
    Author: Stanislav Malyshev <stas@php.net>
    Date: Sat Aug 1 21:45:19 2015 -0700

    Fixed bug #70166 - Use After Free Vulnerability in unserialize() with SPLArrayObject

    diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c
    index a37eced..86608c0 100644
    --- a/ext/spl/spl_array.c
    +++ b/ext/spl/spl_array.c
    @@ -1777,6 +1777,7 @@ SPL_METHOD(Array, unserialize)
    goto outexcept;
    }

    + var_push_dtor(&var_hash, &pflags);
    --p; /* for ';' */
    flags = Z_LVAL_P(pflags);
    /* flags needs to be verified and we also need to verify whether the next
    @@ -1800,6 +1801,7 @@ SPL_METHOD(Array, unserialize)
    if (!php_var_unserialize(&intern->array, &p, s + buf_len, &var_hash TSRMLS_CC)) {
    goto outexcept;
    }
    + var_push_dtor(&var_hash, &intern->array);
    }
    if (*p != ';') {
    goto outexcept;
    @@ -1818,6 +1820,7 @@ SPL_METHOD(Array, unserialize)
    goto outexcept;
    }

    + var_push_dtor(&var_hash, &pmembers);
    /* copy members */
    if (!intern->std.properties) {
    rebuild_object_properties(&intern->std);
    diff --git a/ext/spl/tests/bug70166.phpt b/ext/spl/tests/bug70166.phpt
    new file mode 100644
    index 0000000..51a3596
    --- /dev/null
    +++ b/ext/spl/tests/bug70166.phpt
    @@ -0,0 +1,29 @@
    +--TEST--
    +SPL: Bug #70166 Use After Free Vulnerability in unserialize() with SPLArrayObject
    +--FILE--
    +<?php
    +$inner = 'x:i:1;a:0:{};m:a:0:{}';
    +$exploit = 'a:2:{i:0;C:11:"ArrayObject":'.strlen($inner).':{'.$inner.'}i:1;R:5;}';
    +
    +$data = unserialize($exploit);
    +
    +for($i = 0; $i < 5; $i++) {
    + $v[$i] = 'hi'.$i;
    +}
    +
    +var_dump($data);
    +?>
    +===DONE===
    +--EXPECTF--
    +array(2) {
    + [0]=>
    + object(ArrayObject)#%d (1) {
    + ["storage":"ArrayObject":private]=>
    + array(0) {
    + }
    + }
    + [1]=>
    + array(0) {
    + }
    +}
    +===DONE===