Project: php-src (php/php-src), language: c++
Vulnerability instance: php.cve-2016-10161
Sanitizer: address

================= Bug Report (1/1) ==================
## Source: PHP Bugs
## URL: https://bugs.php.net/bug.php?id=73825
## Description:
PHP Bug ID: 73825
Summary: Heap out of bounds read on unserialize in finish_nested_data()
Status: Closed
PHP Version: 5.6.29
Assigned: stas (profile)
CVE-ID: 2016-10161

Description:
Description:
------------
This PHP code will cause an out of bounds read:

<?php
$obj = unserialize('O:8:"00000000":');

This needs the env variable USE_ZEND_ALLOC=0 set to be reproducible and a memory safety tool like address sanitizer.

Here's the stack trace from asan:
==6025==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60400004bbb9 at pc 0x0000015aed76 bp 0x7ffe872a9cb0 sp 0x7ffe872a9ca8
READ of size 1 at 0x60400004bbb9 thread T0
    #0 0x15aed75 in finish_nested_data /f/php/php-7.1.0/ext/standard/var_unserializer.c:441:6
    #1 0x15aed75 in object_common2 /f/php/php-7.1.0/ext/standard/var_unserializer.c:538
    #2 0x15ab1cc in php_var_unserialize_internal /f/php/php-7.1.0/ext/standard/var_unserializer.c:1255:9
    #3 0x15a1ef6 in php_var_unserialize /f/php/php-7.1.0/ext/standard/var_unserializer.c:550:11
    #4 0x1559b18 in zif_unserialize /f/php/php-7.1.0/ext/standard/var.c:1110:7
    #5 0x1baeb02 in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER /f/php/php-7.1.0/Zend/zend_vm_execute.h:675:2
    #6 0x1a19c25 in execute_ex /f/php/php-7.1.0/Zend/zend_vm_execute.h:432:7
    #7 0x1a1ade6 in zend_execute /f/php/php-7.1.0/Zend/zend_vm_execute.h:474:2
    #8 0x1878bc9 in zend_execute_scripts /f/php/php-7.1.0/Zend/zend.c:1474:4
    #9 0x1637caa in php_execute_script /f/php/php-7.1.0/main/main.c:2533:14
    #10 0x1ce973b in do_cli /f/php/php-7.1.0/sapi/cli/php_cli.c:990:5
    #11 0x1ce663e in main /f/php/php-7.1.0/sapi/cli/php_cli.c:1378:18
    #12 0x7f39bfc6278f in __libc_start_main (/lib64/libc.so.6+0x2078f)
    #13 0x4638e8 in _start (/r/php/php+0x4638e8)

0x60400004bbb9 is located 1 bytes to the right of 40-byte region [0x60400004bb90,0x60400004bbb8)
allocated by thread T0 here:
    #0 0x51cce8 in malloc (/r/php/php+0x51cce8)
    #1 0x178041b in __zend_malloc /f/php/php-7.1.0/Zend/zend_alloc.c:2820:14
    #2 0x1790f37 in zendlex /f/php/php-7.1.0/Zend/zend_compile.c:1701:11
    #3 0x16eba8c in zendparse /f/php/php-7.1.0/Zend/zend_language_parser.c:4217:16
    #4 0x170121a in zend_compile /f/php/php-7.1.0/Zend/zend_language_scanner.l:585:7
    #5 0x1700d51 in compile_file /f/php/php-7.1.0/Zend/zend_language_scanner.l:635:14
    #6 0x11daeed in phar_compile_file /f/php/php-7.1.0/ext/phar/phar.c:3305:9
    #7 0x1878af8 in zend_execute_scripts /f/php/php-7.1.0/Zend/zend.c:1468:14
    #8 0x1637caa in php_execute_script /f/php/php-7.1.0/main/main.c:2533:14
    #9 0x1ce973b in do_cli /f/php/php-7.1.0/sapi/cli/php_cli.c:990:5
    #10 0x1ce663e in main /f/php/php-7.1.0/sapi/cli/php_cli.c:1378:18
    #11 0x7f39bfc6278f in __libc_start_main (/lib64/libc.so.6+0x2078f)

SUMMARY: AddressSanitizer: heap-buffer-overflow /f/php/php-7.1.0/ext/standard/var_unserializer.c:441:6 in finish_nested_data
Shadow bytes around the buggy address:
  0x0c0880001720: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0880001730: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0880001740: fa fa fa fa fa fa fa fa fa fa 00 00 00 00 00 fa
  0x0c0880001750: fa fa 00 00 00 00 00 fa fa fa fd fd fd fd fd fa
  0x0c0880001760: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 00
=>0x0c0880001770: fa fa 00 00 00 00 00[fa]fa fa fd fd fd fd fd fa
  0x0c0880001780: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 00
  0x0c0880001790: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 fa
  0x0c08800017a0: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 00
  0x0c08800017b0: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 00
  0x0c08800017c0: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 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
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==6025==ABORTING


Test script:
---------------
<?php
$obj = unserialize('O:8:"00000000":');

Comments:

[Comment 1] [2016-12-31 01:00 UTC] stas@php.net
The fix is in security repo as 16b3003ffc6393e250f069aa28a78dc5a2c064b2 and in https://gist.github.com/fbc13007bdd5352842d5e071b47aa897

please verify
Links: https://gist.github.com/fbc13007bdd5352842d5e071b47aa897

[Comment 2] [2016-12-31 14:16 UTC] hanno at hboeck dot de
I tried to test that patch, but it applies neither to any current version nor to the current git head.
It seems a lot of that is because var_unserializer.c is somehow generated out of var_unserializer.re and references line numbers. But even skipping the .c file I'm unable to apply it cleanly.

I'd like to test the patch and see if I can find any more issues, can you give me any pointers how I can do that, maybe with a patch that applies on top of 7.1.0?

Commit References:
16b3003ffc6393e250f069aa28a78dc5a2c064b2

Build script:
#!/bin/bash -eu
# Minimized build script with only core build commands
set -eu
./buildconf --force
./configure \
        --enable-option-checking=fatal \
        --disable-libxml \
        --disable-dom \
        --disable-simplexml \
        --disable-xml \
        --disable-xmlreader \
        --disable-xmlwriter \
        --without-pear \
        --enable-exif \
        --disable-phpdbg \
        --disable-cgi
make -j$(nproc)

Dockerfile:
FROM hwiwonlee/secb.base:latest
RUN apt-get update && apt-get install -y make autoconf automake libtool bison re2c make ca-certificates curl xz-utils dpkg-dev file libc-dev pkg-config libcurl4-openssl-dev libedit-dev libsqlite3-dev libssl-dev zlib1g-dev
RUN git clone https://github.com/php/php-src php-src
RUN git -C php-src checkout b28b8b2fee6dfa6fcd13305c581bb835689ac3be
WORKDIR $SRC/php-src
COPY build.sh $SRC/

Additional files: