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

================= Bug Report (1/1) ==================
## Source: PHP Bugs
## URL: https://bugs.php.net/bug.php?id=72061
## Description:
PHP Bug ID: 72061
Summary: Out-of-bounds reads in zif_grapheme_stripos with negative offset
Status: Closed
PHP Version: 5.5.34
Assigned: stas (profile)
CVE-ID: 2016-4540

Description:
Description:
------------
Run with PHP/ASAN

The offset parameter reads from arbitrary memory when a negative value is passed and the first parameter is an array element.

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


$vals =  [ 1, 1, 1, 1, 1, 1, 1,1, 1, 1, 1, 1, 1, 1,1,1, 1, 1, 1, 1,  1, 1,1,1, 1,1, 1, 1, 1, 1, 1,1, 1, 1, 1,1,1,1,1,
           1,1,1, 1, 1, 1,1,1, 1, 1, 1, 1 , 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,1, 1,1, 1,1,1, 1 ,
           str_repeat("ABCD", 16384) ];


grapheme_stripos($vals[76], "A", -201);



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

Actual result:
--------------
==16765==ERROR: AddressSanitizer: heap-buffer-overflow on address 0xb0ebf747 at pc 0xb71b3c35 bp 0xbff95058 sp 0xbff94c2c
READ of size 202 at 0xb0ebf747 thread T0
    #0 0xb71b3c34  (/usr/lib/i386-linux-gnu/libasan.so.2+0x37c34)
    #1 0xaf8e42c5 in zend_memnstr /home/fmunozs/phpgit/php56/Zend/zend_operators.h:280
    #2 0xaf8e42c5 in zif_grapheme_stripos /home/fmunozs/phpgit/php56/ext/intl/grapheme/grapheme_string.c:222
    #3 0x9a7c718 in zend_do_fcall_common_helper_SPEC /home/fmunozs/phpgit/php56/Zend/zend_vm_execute.h:558
    #4 0x9640316 in execute_ex /home/fmunozs/phpgit/php56/Zend/zend_vm_execute.h:363
    #5 0x9a6c9c8 in zend_execute /home/fmunozs/phpgit/php56/Zend/zend_vm_execute.h:388
    #6 0x9470b59 in zend_execute_scripts /home/fmunozs/phpgit/php56/Zend/zend.c:1341
    #7 0x91acc6b in php_execute_script /home/fmunozs/phpgit/php56/main/main.c:2613
    #8 0x9a8648a in do_cli /home/fmunozs/phpgit/php56/sapi/cli/php_cli.c:994
    #9 0x808a502 in main /home/fmunozs/phpgit/php56/sapi/cli/php_cli.c:1378
    #10 0xb6d61645 in __libc_start_main (/lib/i386-linux-gnu/libc.so.6+0x18645)
    #11 0x808aaba  (/home/fmunozs/phpgit/php56/sapi/cli/php+0x808aaba)

0xb0ebf747 is located 185 bytes to the left of 262144-byte region [0xb0ebf800,0xb0eff800)
allocated by thread T0 here:
    #0 0xb7212d06 in malloc (/usr/lib/i386-linux-gnu/libasan.so.2+0x96d06)
    #1 0x92e8597 in zend_mm_mem_malloc_alloc /home/fmunozs/phpgit/php56/Zend/zend_alloc.c:287

SUMMARY: AddressSanitizer: heap-buffer-overflow ??:0 ??
Shadow bytes around the buggy address:
  0x361d7e90: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x361d7ea0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x361d7eb0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x361d7ec0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x361d7ed0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x361d7ee0: fa fa fa fa fa fa fa fa[fa]fa fa fa fa fa fa fa
  0x361d7ef0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x361d7f00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x361d7f10: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x361d7f20: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x361d7f30: 00 00 00 00 00 00 00 00 00 00 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
==16765==ABORTING

Comments:

[Comment 1] [2016-04-24 19:41 UTC] stas@php.net
Looks like some grapheme functions have negative offset handling messed up on ASCII strings.

[Comment 2] [2016-04-24 20:16 UTC] stas@php.net
Fixed in commit fd9689745c44341b1bd6af4756f324be8abba2fb in security repo and in https://gist.github.com/anonymous/2360dd5e33b55938d7eea678a0dd0f9d. Please verify.
Links: https://gist.github.com/anonymous/2360dd5e33b55938d7eea678a0dd0f9d

[Comment 3] [2016-04-25 03:36 UTC] fernando at null-life dot com
Patch works, ASAN stops complaining. Thanks.

[Comment 7] [2016-05-06 06:45 UTC] remi@php.net
Use CVE-2016-4540 for the grapheme_stripos issue.

Use CVE-2016-4541 for the grapheme_strpos issue (separately discovered).

Commit References:
fd9689745c44341b1bd6af4756f324be8abba2fb

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

Additional files: