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

================= Bug Report (1/1) ==================
## Source: PHP Bugs
## URL: https://bugs.php.net/bug.php?id=77753
## Description:
PHP Bug ID: 77753
Summary: Heap-buffer-overflow in php_ifd_get32s
Status: Closed
PHP Version: 7.1.27
Assigned: stas (profile)
CVE-ID: 2019-11034

Description:
Description:
------------
ASAN finds this problem in Exif module:

==6==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60b0000768c5 at pc 0x000000751f93 bp 0x7ffc05a5e170 sp 0x7ffc05a5e168
READ of size 1 at 0x60b0000768c5 thread T0
SCARINESS: 12 (1-byte-read-heap-buffer-overflow)
    #0 0x751f92 in php_ifd_get32s /src/php-src/ext/exif/exif.c:1470:12
    #1 0x74ea93 in exif_process_IFD_TAG /src/php-src/ext/exif/exif.c:3230:15
    #2 0x751cf6 in exif_process_IFD_in_MAKERNOTE /src/php-src/ext/exif/exif.c:3192:8
    #3 0x74fbed in exif_process_IFD_TAG /src/php-src/ext/exif/exif.c:3477:10
    #4 0x74d1a1 in exif_process_IFD_in_TIFF /src/php-src/ext/exif/exif.c:4144:12
    #5 0x74b531 in exif_scan_FILE_header /src/php-src/ext/exif/exif.c:4227:9
    #6 0x74aea7 in exif_read_from_impl /src/php-src/ext/exif/exif.c:4352:8
    #7 0x747100 in exif_read_from_file /src/php-src/ext/exif/exif.c:4396:8
    #8 0x7457e8 in zif_exif_read_data /src/php-src/ext/exif/exif.c:4469:9
    #9 0xd5e4a1 in zend_call_function /src/php-src/Zend/zend_execute_API.c
    #10 0xd5cf5c in _call_user_function_ex /src/php-src/Zend/zend_execute_API.c:627:9
    #11 0x1092512 in fuzzer_call_php_func_zval /src/php-src/sapi/fuzzer/fuzzer-sapi.c:215:11
    #12 0x10928ae in fuzzer_call_php_func /src/php-src/sapi/fuzzer/fuzzer-sapi.c:237:2
    #13 0x109174f in LLVMFuzzerTestOneInput /src/php-src/sapi/fuzzer/fuzzer-exif.c:45:2
    #14 0x10d4d85 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/libfuzzer/FuzzerLoop.cpp:529:15
    #15 0x10950d6 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /src/libfuzzer/FuzzerDriver.cpp:286:6
    #16 0x10a0c03 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/libfuzzer/FuzzerDriver.cpp:715:9
    #17 0x109474c in main /src/libfuzzer/FuzzerMain.cpp:19:10
    #18 0x7f75cb7c082f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #19 0x46f788 in _start (/out/php-fuzz-exif+0x46f788)

0x60b0000768c5 is located 0 bytes to the right of 101-byte region [0x60b000076860,0x60b0000768c5)
allocated by thread T0 here:
    #0 0x5023b2 in malloc /src/llvm/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:145
    #1 0xd0ad39 in __zend_malloc /src/php-src/Zend/zend_alloc.c:2936:14
    #2 0x74f2de in exif_process_IFD_TAG /src/php-src/ext/exif/exif.c:3280:17
    #3 0x74d1a1 in exif_process_IFD_in_TIFF /src/php-src/ext/exif/exif.c:4144:12
    #4 0x74b531 in exif_scan_FILE_header /src/php-src/ext/exif/exif.c:4227:9
    #5 0x74aea7 in exif_read_from_impl /src/php-src/ext/exif/exif.c:4352:8
    #6 0x747100 in exif_read_from_file /src/php-src/ext/exif/exif.c:4396:8
    #7 0x7457e8 in zif_exif_read_data /src/php-src/ext/exif/exif.c:4469:9
    #8 0xd5e4a1 in zend_call_function /src/php-src/Zend/zend_execute_API.c
    #9 0xd5cf5c in _call_user_function_ex /src/php-src/Zend/zend_execute_API.c:627:9
    #10 0x1092512 in fuzzer_call_php_func_zval /src/php-src/sapi/fuzzer/fuzzer-sapi.c:215:11
    #11 0x10928ae in fuzzer_call_php_func /src/php-src/sapi/fuzzer/fuzzer-sapi.c:237:2
    #12 0x109174f in LLVMFuzzerTestOneInput /src/php-src/sapi/fuzzer/fuzzer-exif.c:45:2
    #13 0x10d4d85 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) /src/libfuzzer/FuzzerLoop.cpp:529:15
    #14 0x10950d6 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) /src/libfuzzer/FuzzerDriver.cpp:286:6
    #15 0x10a0c03 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) /src/libfuzzer/FuzzerDriver.cpp:715:9
    #16 0x109474c in main /src/libfuzzer/FuzzerMain.cpp:19:10
    #17 0x7f75cb7c082f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)

Found by OSS-Fuzz in https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=13723

Comments:

[Comment 1] [2019-03-18 04:41 UTC] stas@php.net
The issue seems to be that while this code in exif_process_IFD_in_MAKERNOTE:

 if ((2+NumDirEntries*12) > value_len) {
  exif_error_docref("exif_read_data#error_ifd" EXIFERR_CC, ImageInfo, E_WARNING, "Illegal IFD size: 2 + 0x%04X*12 = 0x%04X > 0x%04X", NumDirEntries, 2+NumDirEntries*12, value_len);
  return FALSE;
 }

checks that there's enough data for directory entries, it does not take offset into account.

[Comment 2] [2019-03-18 04:43 UTC] stas@php.net
The following patch has been added/updated:

Patch Name: fix-overread
Revision:   1552884210
URL:        https://bugs.php.net/patch-display.php?bug=77753&patch=fix-overread&revision=1552884210
Links: https://bugs.php.net/patch-display.php?bug=77753&patch=fix-overread&revision=1552884210

[Comment 3] [2019-03-18 06:04 UTC] stas@php.net
Fix also in security repo as 511883584929c42af9d8122f0e79520c17bb771d

Commit References:
511883584929c42af9d8122f0e79520c17bb771d

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 \
        --enable-mbstring
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 chrpath
RUN git clone https://github.com/php/php-src php-src
RUN git -C php-src checkout dc1cd3daf2521b352b0c9fa6ade7e49a8cc63130
WORKDIR $SRC/php-src
COPY build.sh $SRC/

Additional files:
filename: cosmic.list
content: deb http://archive.ubuntu.com/ubuntu/ cosmic universe


filename: runtime.options
content: [libfuzzer]
detect_leaks=0