|  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #72610 unserialize() read-after-free when property_table is reallocated
Submitted: 2016-07-17 18:12 UTC Modified: 2017-01-16 11:37 UTC
Avg. Score:1.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: tandre at ifwe dot co Assigned: dmitry (profile)
Status: Closed Package: *General Issues
PHP Version: 7.0.8 OS: All
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If this is not your bug, you can add a comment by following this link.
If this is your bug, but you forgot your password, you can retrieve your password here.
Bug Type:
From: tandre at ifwe dot co
New email:
PHP Version: OS:


 [2016-07-17 18:12 UTC] tandre at ifwe dot co
This affects all versions of phpPHP 7.0.0 to PHP 7.1-alpha3

Running the linked 3v4l test script in php 7 will result in the error "Notice: unserialize(): Error at offset 100 of 102 bytes in /in/1SsOJ on line 28"

Versions from php 7.0.0 to php 7.0.2 are affected slightly differently.

Additionally, Running the test script with the bash command `USE_ZEND_ALLOC=0 valgrind php that_file.php` will reveal multiple invalid memory reads of already freed data. See

I'm not sure if this falls under security, change the bug type if it doesn't. (If new objects are allocated, I assume they may overlap with the invalid pointers)

See ext/standard/
The problem is that the var_entries struct contains pointers to `zval`s in the object property_table if that property is dynamic (e.g. no declaration in the class such as `public $a`). 
When the property_table is expanded by realloc(), those pointers usually become invalid.

Possible fixes (not sure if these will work)

- keep a list of copies of those values (instead of pointers) in var_entries (list of `zval` instead of `zval*`) in struct var_entries, and temporarily increment refcount of underlying objects/arrays?
- Defer calls to __wakeup() until after all properties were set up, and perform those calls in the same order they originally would have. This may cause different behavior when unserializing. may or may not be affected by the fix to this bug

Test script:

Expected result:
The program runs without reading free()d/realloc()ed memory. It has the below output:

Called __unserialize
array(2) {
  object(Obj)#4 (1) {
    object(stdClass)#5 (1) {
      string(3) "foo"
  object(Obj)#6 (1) {
    object(stdClass)#5 (1) {
      string(3) "foo"

Actual result:
unserialize performs invalid memory reads, then returns false


Notice: unserialize(): Error at offset 100 of 102 bytes in /in/DkcB5 on line 20
Called __unserialize
Notice: Trying to get property of non-object in /in/DkcB5 on line 24
Fail 0 b0


Add a Patch

Pull Requests

Pull requests:

Add a Pull Request


AllCommentsChangesGit/SVN commitsRelated reports
 [2016-07-17 20:30 UTC]
-Summary: unserialize() +Summary: unserialize() read-after-free when property_table is reallocated
 [2016-07-18 00:43 UTC]
-Type: Security +Type: Bug -Assigned To: +Assigned To: dmitry
 [2016-07-18 00:43 UTC]
Doesn't look like security issue, requires a lot of specialized code.
 [2016-07-18 02:18 UTC] tandre at ifwe dot co
It seems like hhvm handles __wakeup in the same way as the second option I mentioned:

igbinary7 had a similar issue, and a (possibly incomplete) fix for the similar issue was

(The NG engine might require slightly different adjustments)
 [2016-07-18 17:55 UTC] tandre at ifwe dot co
I created a PR to fix this issue: . Comments and any test cases that you think I should add are welcome.

Also, never mind, should be unaffected by the fix, it won't call __wakeup.
 [2017-01-16 11:37 UTC]
-Status: Assigned +Status: Closed
 [2017-01-16 11:37 UTC]
This has been fixed by The change is in 5.6+, even though the property table issue only affects PHP 7, because this also prevents a wide range of other __wakeup() based attacks.
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Wed Feb 28 07:01:28 2024 UTC