php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #77843 Use after free with json serializer
Submitted: 2019-04-04 06:59 UTC Modified: 2019-04-18 14:42 UTC
Votes:1
Avg. Score:3.0 ± 0.0
Reproduced:0 of 0 (0.0%)
From: hanno at hboeck dot de Assigned: nikic (profile)
Status: Closed Package: JSON related
PHP Version: 7.3.3 OS: Linux
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 you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: hanno at hboeck dot de
New email:
PHP Version: OS:

 

 [2019-04-04 06:59 UTC] hanno at hboeck dot de
Description:
------------
Together with a recent apache vulnerability
https://cfreal.github.io/carpe-diem-cve-2019-0211-apache-local-root.html

a use after free 0day bug in PHP was disclosed.

Just want to make sure you're aware of it. Compiling PHP 7.3.3 with ASAN gives me this stack trace:

==22468==ERROR: AddressSanitizer: heap-use-after-free on address 0x606000006288 at pc 0x000001b53104 bp 0x7ffc38a68850 sp 0x7ffc38a68848
READ of size 8 at 0x606000006288 thread T0
    #0 0x1b53103 in ZEND_FETCH_OBJ_R_SPEC_UNUSED_CONST_HANDLER /f/php-7.3.3/Zend/zend_vm_execute.h:31199:8
    #1 0x19ef40c in execute_ex /f/php-7.3.3/Zend/zend_vm_execute.h:55334:7
    #2 0x183aa71 in zend_call_function /f/php-7.3.3/Zend/zend_execute_API.c:756:3
    #3 0x1839366 in _call_user_function_ex /f/php-7.3.3/Zend/zend_execute_API.c:598:9
    #4 0x1197b9a in php_json_encode_serializable_object /f/php-7.3.3/ext/json/json_encoder.c:490:17
    #5 0x1197b9a in php_json_encode_zval /f/php-7.3.3/ext/json/json_encoder.c:567
    #6 0x11a0491 in php_json_encode_array /f/php-7.3.3/ext/json/json_encoder.c:218:8
    #7 0x1197e92 in php_json_encode_zval /f/php-7.3.3/ext/json/json_encoder.c:571:11
    #8 0x11a0491 in php_json_encode_array /f/php-7.3.3/ext/json/json_encoder.c:218:8
    #9 0x1197e92 in php_json_encode_zval /f/php-7.3.3/ext/json/json_encoder.c:571:11
    #10 0x119528c in zif_json_encode /f/php-7.3.3/ext/json/json.c:286:2
    #11 0x1bbbb10 in ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER /f/php-7.3.3/Zend/zend_vm_execute.h:645:2
    #12 0x19ef40c in execute_ex /f/php-7.3.3/Zend/zend_vm_execute.h:55334:7
    #13 0x19efcdf in zend_execute /f/php-7.3.3/Zend/zend_vm_execute.h:60881:2
    #14 0x1889d94 in zend_execute_scripts /f/php-7.3.3/Zend/zend.c:1568:4
    #15 0x16990b7 in php_execute_script /f/php-7.3.3/main/main.c:2630:14
    #16 0x1cc58b3 in do_cli /f/php-7.3.3/sapi/cli/php_cli.c:997:5
    #17 0x1cc23e2 in main /f/php-7.3.3/sapi/cli/php_cli.c:1392:18
    #18 0x7faa220d64fa in __libc_start_main (/lib64/libc.so.6+0x244fa)
    #19 0x424419 in _start (/f/php-7.3.3/sapi/cli/php+0x424419)


Test script:
---------------
<?php

class X extends DateInterval implements JsonSerializable
{
  public function jsonSerialize()
  {
    global $y, $p;
    unset($y[0]);
    $p = $this->y;
    return $this;
  }
}

function get_aslr()
{
  global $p, $y;
  $p = 0;

  $y = [new X('PT1S')];
  json_encode([1234 => &$y]);
  print("ADDRESS: 0x" . dechex($p) . "\n");

  return $p;
}

get_aslr();



Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-04-04 07:07 UTC] stas@php.net
-Type: Security +Type: Bug -Package: Reproducible crash +Package: JSON related
 [2019-04-04 07:07 UTC] stas@php.net
This looks like it requires specially crafted code, therefore not a security issue.
 [2019-04-18 14:42 UTC] nikic@php.net
-Assigned To: +Assigned To: nikic
 [2019-04-18 14:42 UTC] nikic@php.net
Slightly simplified test code (valgrind):

class X implements JsonSerializable {
    public $prop = "value";
    public function jsonSerialize() {
        global $arr;
        unset($arr[0]);
        var_dump($this);
        return $this;
    }
}

$arr = [new X()];
var_dump(json_encode([&$arr]));

We need to make sure a ref is kept when calling jsonSerialize() and probably also when recursing over arrays/objects in general (as something may be unset at a higher level).
 [2019-04-23 10:44 UTC] nikic@php.net
Automatic comment on behalf of nikita.ppv@gmail.com
Revision: http://git.php.net/?p=php-src.git;a=commit;h=4831e150c5ada631c1480098b8a42cbf024d8899
Log: Fixed bug #77843
 [2019-04-23 10:44 UTC] nikic@php.net
-Status: Assigned +Status: Closed
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Dec 03 17:01:29 2024 UTC