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())
media-libs/gd-2.0.35 USE="fontconfig jpeg png truetype xpm"
1. Emerges on AMD64.
2. No collisions.
3. Test phase ok.
4. Multilib-strict ok.
5. Works - tested with app-admin/webalizer, app-text/dvipng, dev-perl/GD,
dev-perl/GDGraph, dev-ruby/ruby-gd, net-analyzer/ntop and www-apps/gallery.
Portage 2.1.2.9 (default-linux/amd64/2007.0/desktop, gcc-4.1.2, glibc-2.5-r4,
2.6.20-gentoo-r8 x86_64)
=================================================================
System uname: 2.6.20-gentoo-r8 x86_64 Intel(R) Pentium(R) D CPU 3.00GHz
Gentoo Base System release 1.12.9
Timestamp of tree: Fri, 20 Jul 2007 21:50:01 +0000
ccache version 2.4 [enabled]
dev-java/java-config: 1.3.7, 2.0.33-r1
dev-lang/python: 2.4.4-r4
dev-python/pycrypto: 2.0.1-r5
dev-util/ccache: 2.4-r7
sys-apps/sandbox: 1.2.17
sys-devel/autoconf: 2.13, 2.61
sys-devel/automake: 1.4_p6, 1.5, 1.6.3, 1.7.9-r1, 1.8.5-r3, 1.9.6-r2, 1.10
sys-devel/binutils: 2.17
sys-devel/gcc-config: 1.3.16
sys-devel/libtool: 1.5.23b
virtual/os-headers: 2.6.21
ACCEPT_KEYWORDS="amd64"
AUTOCLEAN="yes"
CBUILD="x86_64-pc-linux-gnu"
CFLAGS="-O2 -march=nocona -pipe"
CHOST="x86_64-pc-linux-gnu"
CONFIG_PROTECT="/etc /usr/kde/3.5/env /usr/kde/3.5/share/config
/usr/kde/3.5/shutdown /usr/share/X11/xkb /usr/share/config"
CONFIG_PROTECT_MASK="/etc/env.d /etc/env.d/java/ /etc/gconf /etc/init.d
/etc/php/apache2-php5/ext-active/ /etc/php/cgi-php5/ext-active/
/etc/php/cli-php5/ext-active/ /etc/revdep-rebuild /etc/terminfo"
CXXFLAGS="-O2 -march=nocona -pipe"
DISTDIR="/usr/portage/distfiles"
EMERGE_DEFAULT_OPTS="-k"
FEATURES="ccache collision-protect distlocks metadata-transfer multilib-strict
parallel-fetch sandbox sfperms strict test userfetch userpriv usersandbox"
GENTOO_MIRRORS="ftp://mirrors1.netvisao.pt/gentoo
http://darkstar.ist.utl.pt/pub/gentoo http://distfiles.gentoo.org
http://www.ibiblio.org/pub/Linux/distributions/gentoo"
MAKEOPTS="-j3"
PKGDIR="/usr/portage/packages"
PORTAGE_RSYNC_OPTS="--recursive --links --safe-links --perms --times --compress
--force --whole-file --delete --delete-after --stats --timeout=180
--exclude=/distfiles --exclude=/local --exclude=/packages
--filter=H_**/files/digest-*"
PORTAGE_TMPDIR="/var/tmp"
PORTDIR="/usr/portage"
SYNC="rsync://rsync.europe.gentoo.org/gentoo-portage"
USE="X acl acpi alsa amd64 apache2 arts bash-completion bitmap-fonts cairo cdr
cli cracklib crypt dbus dri dts dvd dvdr dvdread emboss encode evo fam firefox
flac fortran gif gnome gpm gtk hal iconv ipv6 isdnlog jpeg kde kdeenablefinal
kdehiddenvisibility libg++ mad midi mikmod mmx mp3 mpeg mudflap musepack
musicbrainz mysql ncurses nptl nptlonly offensive ogg opengl openmp pam pcre
pdf perl png postgres pppd python qt3 qt3support qt4 quicktime readline
reflection sdl session spell spl sse sse2 ssl svg tcpd test tiff truetype
truetype-fonts type1-fonts unicode vorbis xcomposite xml xorg xscreensaver xv
zlib" ALSA_CARDS="ali5451 als4000 atiixp atiixp-modem bt87x ca0106 cmipci
emu10k1x ens1370 ens1371 es1938 es1968 fm801 hda-intel intel8x0 intel8x0m
maestro3 trident usb-audio via82xx via82xx-modem ymfpci"
ALSA_PCM_PLUGINS="adpcm alaw asym copy dmix dshare dsnoop empty extplug file
hooks iec958 ioplug ladspa lfloat linear meter mulaw multi null plug rate route
share shm softvol" ELIBC="glibc" INPUT_DEVICES="keyboard mouse" KERNEL="linux"
LCD_DEVICES="bayrad cfontz cfontz633 glk hd44780 lb216 lcdm001 mtxorb ncurses
text" USERLAND="GNU" VIDEO_CARDS="i810"
Unset: CTARGET, INSTALL_MASK, LANG, LC_ALL, LDFLAGS, LINGUAS,
PORTAGE_COMPRESS, PORTAGE_COMPRESS_FLAGS, PORTAGE_RSYNC_EXTRA_OPTS,
PORTDIR_OVERLAY