Menu

#540 gm: heap-buffer-overflow in ReadTIFFImage (src/coders/tiff.c)

v1.0_(example)
closed-works-for-me
None
5
2018-12-18
2018-01-12
No

on 1.3.27 (the latest version):

there is a heap-based buffer overflow in the ReadTIFFImage function (src/coders/tiff.c), which can be triggered by the POC in the attachment with AddressSanitizer enabled.

gm convert $POC OUTPUT

==36059==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60200000ed32 at pc 0x7f0485f37565 bp 0x7fffc6fce590 sp 0x7fffc6fcdd40

READ of size 15 at 0x60200000ed32 thread T0

#0 0x7f0485f37564 in asan_memcpy ../../../../src/libsanitizer/asan/asan_interceptors.cc:367

#1 0x9f2b65 in ReadTIFFImage (/home/youwei/ProbeFuzzer/product/graphicsmagick/master/exe_sat/bin/gm+0x9f2b65)

#2 0x4981d7 in ReadImage (/home/youwei/ProbeFuzzer/product/graphicsmagick/master/exe_sat/bin/gm+0x4981d7)

#3 0x427921 in ConvertImageCommand (/home/youwei/ProbeFuzzer/product/graphicsmagick/master/exe_sat/bin/gm+0x427921)

#4 0x443a13 in MagickCommand (/home/youwei/ProbeFuzzer/product/graphicsmagick/master/exe_sat/bin/gm+0x443a13)

#5 0x47be14 in GMCommandSingle (/home/youwei/ProbeFuzzer/product/graphicsmagick/master/exe_sat/bin/gm+0x47be14)

#6 0x47c0bc in GMCommand (/home/youwei/ProbeFuzzer/product/graphicsmagick/master/exe_sat/bin/gm+0x47c0bc)

#7 0x40d9b7 in main (/home/youwei/ProbeFuzzer/product/graphicsmagick/master/exe_sat/bin/gm+0x40d9b7)

#8 0x38c3c1ed1c in libc_start_main (/lib64/libc.so.6+0x38c3c1ed1c)

#9 0x40d858 (/home/youwei/ProbeFuzzer/product/graphicsmagick/master/exe_sat/bin/gm+0x40d858)

0x60200000ed32 is located 0 bytes to the right of 2-byte region [0x60200000ed30,0x60200000ed32)

allocated by thread T0 here:

#0 0x7f0485f4306a in interceptor_malloc ../../../../src/libsanitizer/asan/asan_malloc_linux.cc:62

#1 0x38d820ba14 (/usr/lib64/libtiff.so.3+0x38d820ba14)

SUMMARY: AddressSanitizer: heap-buffer-overflow ../../../../src/libsanitizer/asan/asan_interceptors.cc:367 asan_memcpy

Shadow bytes around the buggy address:

0x0c047fff9d50: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa

0x0c047fff9d60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa

0x0c047fff9d70: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa

0x0c047fff9d80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa

0x0c047fff9d90: fa fa fa fa fa fa fa fa fa fa 04 fa fa fa fd fa

=>0x0c047fff9da0: fa fa 04 fa fa fa[02]fa fa fa fd fd fa fa 00 fa

0x0c047fff9db0: fa fa 00 04 fa fa 00 fa fa fa fd fa fa fa fd fa

0x0c047fff9dc0: fa fa fd fd fa fa 00 04 fa fa fd fd fa fa 00 04

0x0c047fff9dd0: fa fa 00 04 fa fa 00 04 fa fa 00 04 fa fa 00 04

0x0c047fff9de0: fa fa 00 04 fa fa 00 04 fa fa 00 04 fa fa 00 04

0x0c047fff9df0: fa fa 00 04 fa fa 00 04 fa fa fd fa fa fa 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

==36059==ABORTING

**

1 Attachments

Discussion

  • Bob Friesenhahn

    Bob Friesenhahn - 2018-01-12
    • assigned_to: Bob Friesenhahn
    • private: No --> Yes
     
  • Bob Friesenhahn

    Bob Friesenhahn - 2018-01-12

    I am not able to reproduce this issue. What version of libtiff and libjpeg are being used? Is this a 64-bit or 32-bit build? Please post the full output from 'gm -version'.

    This issue could easily be due to a bug already fixed in libtiff or related to a specific libjpeg distribution/version. I do see libtiff making two security-related corrections to the TIFF parsing. I also see that the file uses old JPEG compression TIFF format.

     
    • Probe Fuzzer

      Probe Fuzzer - 2018-01-12

      Thanks for your work.
      It is a 64-bt build with address sanitizer enables (CFLAGS=-fsanitize=address).

      I have git pull the latest commit of libtiff and libjpeg and place the code in tiff and jpeg folders of graphicmagick source code. After complication, I can still reproduce this issue.
      Did you complie with address sanitizer enabled (i.e., CFLAGS=-fsanitize=address)?

      You said that you saw libtiff making two security-related corrections to the TIFF parsing. Could you please send me the references URL to these two issues. I will check whehter my issue is different from these two. Thank you .

      The output of ”gm -version" is like below:
      GraphicsMagick 1.4 snapshot-20180107 Q8 http://www.GraphicsMagick.org/
      Copyright (C) 2002-2018 GraphicsMagick Group.
      Additional copyrights and licenses apply to this software.
      See http://www.GraphicsMagick.org/www/Copyright.html for details.

      Feature Support:
      Native Thread Safe yes
      Large Files (> 32 bit) yes
      Large Memory (> 32 bit) yes
      BZIP yes
      DPS no
      FlashPix no
      FreeType yes
      Ghostscript (Library) no
      JBIG no
      JPEG-2000 yes
      JPEG yes
      Little CMS no
      Loadable Modules no
      OpenMP yes (201307)
      PNG yes
      TIFF yes
      TRIO no
      UMEM no
      WebP yes
      WMF yes
      X11 yes
      XML yes
      ZLIB yes

      Host type: x86_64-unknown-linux-gnu

      Configured using the command:
      /u/ProbeFuzzer/ProbeFuzzer/product/graphicsmagick/master/src/configure '--prefix=/u/ProbeFuzzer/ProbeFuzzer/product/graphicsmagick/master/exe_asan' 'CC=/u/ProbeFuzzer/ProbeFuzzer/afl/afl-gcc' 'CFLAGS=-fsanitize=address' 'LDFLAGS=-fsanitize=address' 'CXX=/u/ProbeFuzzer/ProbeFuzzer/afl/afl-g++' 'CXXFLAGS=-fsanitize=address'

      Final Build Parameters:
      CC = /u/ProbeFuzzer/ProbeFuzzer/afl/afl-gcc
      CFLAGS = -fopenmp -fsanitize=address -Wall
      CPPFLAGS = -I/usr/include/freetype2 -I/usr/include/libxml2
      CXX = /u/ProbeFuzzer/ProbeFuzzer/afl/afl-g++
      CXXFLAGS = -fsanitize=address
      LDFLAGS = -fsanitize=address
      LIBS = -lwebp -lwebpmux -ltiff -lfreetype -ljasper -ljpeg -lpng12 -lwmflite -lXext -lSM -lICE -lX11 -llzma -lbz2 -lxml2 -lz -lm -lgomp -lpthread

       
      • Bob Friesenhahn

        Bob Friesenhahn - 2018-01-12

        On Fri, 12 Jan 2018, Probe Fuzzer wrote:

        Thanks for your work.
        It is a 64-bt build with address sanitizer enables (CFLAGS=-fsanitize=address).

        I have git pull the latest commit of libtiff and libjpeg and place the code in tiff and jpeg folders of graphicmagick source code. After complication, I can still reproduce this issue.
        Did you complie with address sanitizer enabled (i.e., CFLAGS=-fsanitize=address)?

        You need to be clear about what is meant by "libjpeg" since there are
        two major "libjpeg" projects now (as well as two other splinter
        projects). I am using IJG JPEG (IJG JPEG 80), which historically has
        fewer anomalies than TurboJPEG. One reason why I am using IJG JPEG is
        so that the GraphicsMagick test suite could pass with valgrind and
        ASAN.

        I tested with ASAN and valgrind.

        You said that you saw libtiff making two security-related
        corrections to the TIFF parsing. Could you please send me the
        references URL to these two issues. I will check whehter my issue is
        different from these two. Thank you .

        If you add '-debug coder' to the options, you will then see many
        warnings from libtiff, many of which say that it made a correction:

        08:01:27 0:01 0.000u 15498 tiff.c/unknown/1007/Coder:
        TIFF Warning: Invalid TIFF directory; tags are not sorted in
        ascending order.
        08:01:27 0:01 0.000u 15498 tiff.c/unknown/1007/Coder:
        TIFF Warning: Unknown field with tag 32781 (0x800d) encountered.
        08:01:27 0:01 0.000u 15498 tiff.c/unknown/1007/Coder:
        TIFF Warning: Unknown field with tag 384 (0x180) encountered.
        08:01:27 0:01 0.000u 15498 tiff.c/unknown/1007/Coder:
        TIFF Warning: Unknown field with tag 1093 (0x445) encountered.
        08:01:27 0:01 0.000u 15498 tiff.c/unknown/1007/Coder:
        TIFF Warning: Unknown field with tag 2 (0x2) encountered.
        08:01:27 0:01 0.000u 15498 tiff.c/unknown/1007/Coder:
        TIFF Warning: ASCII value for tag "Tag 32781" does not end in null
        byte. Forcing it to be null.
        08:01:27 0:01 0.000u 15498 tiff.c/unknown/1007/Coder:
        TIFF Warning: Incorrect count for "JpegProc"; tag ignored.
        08:01:27 0:01 0.000u 15498 tiff.c/unknown/1007/Coder:
        TIFF Warning: Photometric tag value assumed incorrect, assuming data
        is YCbCr instead of RGB.
        08:01:27 0:01 0.000u 15498 tiff.c/unknown/1007/Coder:
        TIFF Warning: SamplesPerPixel tag is missing, applying correct
        SamplesPerPixel value of 3.
        08:01:27 0:01 0.000u 15498 tiff.c/unknown/1007/Coder:
        TIFF Warning: SamplesPerPixel tag value is changing, but
        SMinSampleValue tag was read with a different value. Cancelling it.

        I am suspecting that the small error which was detected can be
        attributed to libjpeg behavior.

        Bob

         
        • Probe Fuzzer

          Probe Fuzzer - 2018-01-13

          Thanks for your reply.
          We have checked the issue carefully and found it is a bug in libtiff, which got fixed in the latest version of libtiff.
          Thanks again.

           
          • Salvatore Bonaccorso

            Hi

            Can you point to which libtiff upstream change did fix the issue?

             
  • Bob Friesenhahn

    Bob Friesenhahn - 2018-01-13
    • status: open --> closed-works-for-me
    • private: Yes --> No
     
  •  kirotawa

    kirotawa - 2018-06-28

    Hi Bob,

    what is commit that fix this issue?

    Thanks!

     
    • Bob Friesenhahn

      Bob Friesenhahn - 2018-06-28

      On Thu, 28 Jun 2018, kirotawa wrote:

      Hi Bob,

      what is commit that fix this issue?

      That is a good question since it was already fixed by the time the
      problem was reported and so there is no specific change entry for this
      POC.

      If you really need to know, then I suggest studying the Mercurial
      commits to coders/tiff.c and read the entries in the ChangeLog files.

      Bob

       
  • Hugo Lefeuvre

    Hugo Lefeuvre - 2018-12-18

    In can confirm that this issue was a bug in the libTIFF codebase, namely http://bugzilla.maptools.org/show_bug.cgi?id=2500

    The reproducer does not declare SamplesPerPixel field, so libTIFF does some guessing to set the correct value. Unfortunately it does not update the SMinSampleValue value, leading to later crash.

    It was fixed in 739dcd28 (https://gitlab.com/libtiff/libtiff/commit/739dcd28a061738b317c1e9f91029d9cbc157159)

    You can reproduce the issue by building a pre-739dcd28 libTIFF with asan:

    $ ./tools/tiffset ./graphicsmagic_0.tif
    TIFFReadDirectoryCheckOrder: Warning, Invalid TIFF directory; tags are not sorted in ascending order.
    TIFFReadDirectory: Warning, Unknown field with tag 32781 (0x800d) encountered.
    TIFFReadDirectory: Warning, Unknown field with tag 384 (0x180) encountered.
    TIFFReadDirectory: Warning, Unknown field with tag 1093 (0x445) encountered.
    TIFFReadDirectory: Warning, Unknown field with tag 2 (0x2) encountered.
    TIFFFetchNormalTag: Warning, Incorrect count for "JpegProc"; tag ignored.
    TIFFReadDirectory: Warning, Photometric tag value assumed incorrect, assuming data is YCbCr instead of RGB.
    TIFFReadDirectory: Warning, SamplesPerPixel tag is missing, applying correct SamplesPerPixel value of 3.
    =================================================================
    ==6139==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000118 at pc 0x7f56213cf283 bp 0x7ffc20a95f90 sp 0x7ffc20a95f88
    READ of size 8 at 0x602000000118 thread T0
        #0 0x7f56213cf282 in TIFFWriteDirectoryTagSampleformatArray /home/hle/Development/C/libtiff/libtiff/tif_dirwrite.c:994
        #1 0x7f56213cb352 in TIFFWriteDirectorySec /home/hle/Development/C/libtiff/libtiff/tif_dirwrite.c:577
        #2 0x7f56213c7f01 in TIFFWriteDirectory /home/hle/Development/C/libtiff/libtiff/tif_dirwrite.c:183
        #3 0x7f56213c95d8 in TIFFRewriteDirectory /home/hle/Development/C/libtiff/libtiff/tif_dirwrite.c:359
        #4 0x557fb2e29c1d in main /home/hle/Development/C/libtiff/tools/tiffset.c:344
        #5 0x7f5620772b16 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x22b16)
        #6 0x557fb2e282d9 in _start (/home/hle/Development/C/libtiff/tools/.libs/tiffset+0x22d9)
    
    0x602000000118 is located 0 bytes to the right of 8-byte region [0x602000000110,0x602000000118)
    allocated by thread T0 here:
        #0 0x7f56215b5ed0 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0xe8ed0)
        #1 0x7f562147b780 in _TIFFmalloc /home/hle/Development/C/libtiff/libtiff/tif_unix.c:316
        #2 0x7f562138dd55 in setByteArray /home/hle/Development/C/libtiff/libtiff/tif_dir.c:53
        #3 0x7f562138df41 in _TIFFsetDoubleArray /home/hle/Development/C/libtiff/libtiff/tif_dir.c:73
        #4 0x7f562139088e in _TIFFVSetField /home/hle/Development/C/libtiff/libtiff/tif_dir.c:279
        #5 0x7f5621436768 in OJPEGVSetField /home/hle/Development/C/libtiff/libtiff/tif_ojpeg.c:600
        #6 0x7f5621397b95 in TIFFVSetField /home/hle/Development/C/libtiff/libtiff/tif_dir.c:822
        #7 0x7f56213975c8 in TIFFSetField /home/hle/Development/C/libtiff/libtiff/tif_dir.c:766
        #8 0x7f56213ba65c in TIFFReadDirectory /home/hle/Development/C/libtiff/libtiff/tif_dirread.c:3711
        #9 0x7f562144a66f in TIFFClientOpen /home/hle/Development/C/libtiff/libtiff/tif_open.c:466
        #10 0x7f562147b4e6 in TIFFFdOpen /home/hle/Development/C/libtiff/libtiff/tif_unix.c:211
        #11 0x7f562147b73f in TIFFOpen /home/hle/Development/C/libtiff/libtiff/tif_unix.c:250
        #12 0x557fb2e285c0 in main /home/hle/Development/C/libtiff/tools/tiffset.c:86
        #13 0x7f5620772b16 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x22b16)
    
    SUMMARY: AddressSanitizer: heap-buffer-overflow /home/hle/Development/C/libtiff/libtiff/tif_dirwrite.c:994 in TIFFWriteDirectoryTagSampleformatArray
    Shadow bytes around the buggy address:
      0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      0x0c047fff8000: fa fa 00 00 fa fa fd fa fa fa fd fd fa fa 00 07
      0x0c047fff8010: fa fa fd fa fa fa 00 fa fa fa fd fa fa fa fd fa
    =>0x0c047fff8020: fa fa 00[fa]fa fa fd fa fa fa 04 fa fa fa fa fa
      0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      0x0c047fff8060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
      0x0c047fff8070: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa 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
      Freed heap region:       fd
      Stack left redzone:      f1
      Stack mid redzone:       f2
      Stack right redzone:     f3
      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
    ==6139==ABORTING
    
     

Log in to post a comment.