Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Invalid read when call gdImageTiffPtr (CVE-2017-6363) #383

Closed
varsleak opened this issue Feb 17, 2017 · 7 comments
Closed

Invalid read when call gdImageTiffPtr (CVE-2017-6363) #383

varsleak opened this issue Feb 17, 2017 · 7 comments
Labels
Milestone

Comments

@varsleak
Copy link

Description

Hi, when I fuzz the libgd, a invalid read occurs within the function tiffWriter of gd_tiff.c, it can be triggered by the
gdfile.txt

Valgrind tracker

➜  Bin git:(master) ✗ valgrind --leak-check=yes ./test_gd2_bug00209 ../../ddms/Bin/gdfile.gd  
==31702== Memcheck, a memory error detector
==31702== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==31702== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==31702== Command: ./test_gd2_bug00209 ../../ddms/Bin/gdfile.gd
==31702== 
==31702== Invalid read of size 4
==31702==    at 0x4E6F318: tiffWriter (gd_tiff.c:267)
==31702==    by 0x4E6FD24: gdImageTiffCtx (gd_tiff.c:446)
==31702==    by 0x4E712DF: gdImageTiffPtr (gd_tiff.c:1067)
==31702==    by 0x40158F: main (bug00209.c:36)
==31702==  Address 0x8177bdc is 249,468 bytes inside an unallocated block of size 4,104,832 in arena "client"
==31702== 
==31702== Invalid read of size 4
==31702==    at 0x4E6F365: tiffWriter (gd_tiff.c:268)
==31702==    by 0x4E6FD24: gdImageTiffCtx (gd_tiff.c:446)
==31702==    by 0x4E712DF: gdImageTiffPtr (gd_tiff.c:1067)
==31702==    by 0x40158F: main (bug00209.c:36)
==31702==  Address 0x8177fdc is 250,492 bytes inside an unallocated block of size 4,104,832 in arena "client"
==31702== 
==31702== Invalid read of size 4
==31702==    at 0x4E6F3AD: tiffWriter (gd_tiff.c:269)
==31702==    by 0x4E6FD24: gdImageTiffCtx (gd_tiff.c:446)
==31702==    by 0x4E712DF: gdImageTiffPtr (gd_tiff.c:1067)
==31702==    by 0x40158F: main (bug00209.c:36)
==31702==  Address 0x81783dc is 251,516 bytes inside an unallocated block of size 4,104,832 in arena "client"
==31702== 
==31702== 
==31702== HEAP SUMMARY:
==31702==     in use at exit: 72,704 bytes in 1 blocks
@vapier
Copy link
Member

vapier commented Feb 17, 2017

please post all code you're using to test things

@varsleak
Copy link
Author

varsleak commented Feb 18, 2017

int main(int argc, char * argv[])
{
    gdImagePtr im = 0;
    FILE *fp = 0;
    void * im2 = 0;
    int size = 0;

    if (argc != 2) return -1;

    fp = fopen(argv[1], "rb");
    if (fp){
	    im = gdImageCreateFromGd(fp);

	    if (im){
	    	im2 = gdImageTiffPtr(im, &size);

	    	if (im2){
	    		gdFree(im2);
	    	}
	    	gdImageDestroy(im);
		}
	    
	}

    fclose(fp);

    return gdNumFailures();
}

The other image lead to heap-buffer-overflow.May be the same mistake.

The ASAN crash log:

➜  Bin git:(master) ✗ ./test_gd2_bug00209 heap-overflow.gd         
=================================================================
==8350==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x624000015bc4 at pc 0x7f4ed7593905 bp 0x7ffeb6df2f50 sp 0x7ffeb6df2f40
READ of size 4 at 0x624000015bc4 thread T0
    #0 0x7f4ed7593904 in tiffWriter /home/xrym/libgd/libgd.bak/src/gd_tiff.c:267
    #1 0x7f4ed75951d0 in gdImageTiffCtx /home/xrym/libgd/libgd.bak/src/gd_tiff.c:446
    #2 0x7f4ed7597a97 in gdImageTiffPtr /home/xrym/libgd/libgd.bak/src/gd_tiff.c:1067
    #3 0x401aca in main /home/xrym/libgd/libgd.bak/tests/gd2/bug00209.c:36
    #4 0x7f4ed716f82f in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
    #5 0x4018a8 in _start (/home/xrym/libgd/ddms/Bin/test_gd2_bug00209+0x4018a8)

AddressSanitizer can not describe address in more detail (wild memory access suspected).
SUMMARY: AddressSanitizer: heap-buffer-overflow /home/xrym/libgd/libgd.bak/src/gd_tiff.c:267 tiffWriter
Shadow bytes around the buggy address:
  0x0c487fffab20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c487fffab30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c487fffab40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c487fffab50: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c487fffab60: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c487fffab70: fa fa fa fa fa fa fa fa[fa]fa fa fa fa fa fa fa
  0x0c487fffab80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c487fffab90: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c487fffaba0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c487fffabb0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c487fffabc0: 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
  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
==8350==ABORTING

@varsleak
Copy link
Author

CVE-2017-6363 was assigned.

@vapier vapier changed the title Invalid read when call gdImageTiffPtr Invalid read when call gdImageTiffPtr (CVE-2017-6363) Feb 28, 2017
vapier added a commit that referenced this issue Jan 31, 2018
The gd image formats allow for a palette of 256 colors,
so if the transparent index is out of range, disable it.
vapier added a commit that referenced this issue Jan 31, 2018
The gd image formats allow for a palette of 256 colors,
so if the transparent index is out of range, disable it.

(cherry picked from commit 0be86e1)
@vapier vapier added the bug label Jan 31, 2018
@vapier vapier added this to the GD 2.2.6 milestone Jan 31, 2018
@vapier
Copy link
Member

vapier commented Jan 31, 2018

the gd image readers should have clamped the transparent index to a valid range. i imagine you'd get a similar error if you tried to output to other image formats as we don't do bounds checking at output time (as we assume the inputs were correct to begin with).

i fixed the issue in the gd/gd2 image readers.

@vapier vapier closed this as completed Jan 31, 2018
cmb69 added a commit that referenced this issue Feb 3, 2018
When reading images in GD or GD2 format, we have to ensure that the
transparent color is not set, if it would refer to a non-extant palette
entry.

We back that up with respective regression tests.
@cmb69
Copy link
Contributor

cmb69 commented Feb 3, 2018

In my opinion this issue should not have a CVE, since the GD and GD2 formats are documented to be "obsolete, and should only be used for development and testing purposes."

@vapier
Copy link
Member

vapier commented Feb 3, 2018

it's too late at this point ;). but regardless of our opinion on the formats, if they're available by default (and they have been), it means people using gd to accept arbitrary inputs from people (like php) are affected.

@cmb69
Copy link
Contributor

cmb69 commented Feb 4, 2018

Well, wrt. PHP the CVE is most likely irrelevant. Firstly, PHP does not have TIFF support (and rather likely the CVE is about this), and secondly, neither GIF, GD(2) nor PNG writing would exhibit a direct vulnerability – the GIF writer just writes the byte, the GD(2) writer also does this, while the PNG writer already caters to out-of-bounds values. The TIFF writer, however, would cause an invalid read. The other writers appear to be agnostic to the transparent color.

Generally, I agree, though – we can't know what users of libgd are doing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants