GD is an open source code library for the dynamic creation of images by programmers. GD is written in C, and “wrappers” are available for Perl, PHP and other languages. GD creates PNG, JPEG and GIF images, among other formats. GD is commonly used to generate charts, graphics, thumbnails, and most anything else, on the fly. While not restricted to use on the web, the most common applications of GD involve web site development.
See the GD website for more informations.
FS#86 — Possible infinite loop in libgd/gd_png.c (inside png_set_read_fn() callback) with truncated input
Opened by Xavier Roche (xroche) - Wednesday, 16 May 2007, 14:12 GMT+2
Last edited by Pierre Joye (Pierre) - Thursday, 17 May 2007, 16:50 GMT+2
|
DetailsHi folks, The following test case using libgd 2.0.34 apparently leads to an infinite loop in the libpng decoder. The infinite loop seems to occur between the libpng code (png_read_data()) and the libgd callback (gdPngReadData()) which may not properly detect truncated input. The libpng’s png_read_info() function hence never returns, and the library consumme 100% CPU.
/* id: gdbad3.c, Xavier Roche, May. 2007 */
/* gcc gdbad3.c -o bad -lgd && ./bad */
#include <stdio.h>
#include <stdlib.h>
#include "gd.h"
static const unsigned char pngdata[93];
int main(void) {
gdImagePtr im;
if ( ( im = gdImageCreateFromPngPtr(93, (char*) &pngdata[0]) ) != NULL) {
fprintf(stderr, "success!\n");
gdImageDestroy(im);
} else {
fprintf(stderr, "failed!\n");
}
return 0;
}
/* PNG data */
static const unsigned char pngdata[93] = {137,80,78,71,13,10,26,10,0,0,
0,13,73,72,68,82,0,0,0,120,0,0,0,131,8,6,0,0,0,70,49,223,8,0,0,0,6,98,
75,71,68,0,255,0,255,0,255,160,189,167,147,0,0,0,9,112,72,89,115,0,0,92,
70,0,0,92,70,1,20,148,67,65,0,0,0,9,118,112,65,103,0,0,0,120,0,0,0,131,
0,226,13,249,45};
Typical stack:
(gdb) where
#0 gdPngReadData (png_ptr=0x501090, data=0x501570 "", length=5247120) at gd_png.c:83
#1 0x00002af9ef5ab192 in png_read_data (png_ptr=0x501090, data=0x501570 "", length=9) at pngrio.c:33
#2 0x00002af9ef5a1935 in png_crc_read (png_ptr=0x501090, buf=0x501570 "", length=9) at pngrutil.c:96
#3 0x00002af9ef5a1a17 in png_crc_finish (png_ptr=0x501090, skip=5248368) at pngrutil.c:116
#4 0x00002af9ef5a425a in png_handle_unknown (png_ptr=0x501090, info_ptr=0x505ae0, length=9)
at pngrutil.c:2221
#5 0x00002af9ef5a9e0d in png_read_info (png_ptr=0x501090, info_ptr=0x505ae0) at pngread.c:530
#6 0x00002af9eeb2baf9 in gdImageCreateFromPngCtx (infile=0x501010) at gd_png.c:189
#7 0x00002af9eeb2b9b0 in gdImageCreateFromPngPtr (size=5247120, data=0x501570) at gd_png.c:111
#8 0x00000000004006df in main ()
(if you ‘up’ to png_read_info() and try ‘finish’, you’ll see that this function never returns due to endless calls to gdPngReadData()) |
Thursday, 17 May 2007, 16:50 GMT+2
Reason for closing: Fixed
Additional comments about closing: Commit in GD_2_0 and HEAD (2.1)
I cannot test it right now but have you tried to read it directly with the libpng (sample codes for example)?
At this stage, gd has no control over the reading process, we checked the signature and then pass the data to the libpng. The backtrace looks like you are refering to CVE-2007-2445, which is a libpng issue and fixed in libpng 1.2.17. Is it correct?
The issue was reproduced with libpng 1.2.18.
The libpng "pngtest" example detect the truncated file, and fails (no infinite loop):
Something wicked must happend inside gdPngReadData()
Problem found, readdata should have been updated to be synced with libpng recommended usage.
Please try the attached patch, it should fix the problem. If everything works well, it will be part of 2.0.35RC4.
Thanks again for the detailed report!
Looks fine after the patch! Thanks! :p
For the record, I just applied the fix to php's libgd. It will be available in the php releases (4.4.8, 5.2.3 and later).
It is now referenced as CVE-2007-2756.