--- pngrutil.c 2010-06-26 02:31:14.000000000 +0200 +++ pngrutil.c.oden 2010-08-14 12:26:20.851624242 +0200 @@ -144,13 +144,11 @@ png_crc_read(png_structp png_ptr, png_by png_calculate_crc(png_ptr, buf, length); } -/* Optionally skip data and then check the CRC. Depending on whether we - * are reading a ancillary or critical chunk, and how the program has set - * things up, we may calculate the CRC on the data and print a message. - * Returns '1' if there was a CRC error, '0' otherwise. - */ -int /* PRIVATE */ -png_crc_finish(png_structp png_ptr, png_uint_32 skip) +/* Workaround for memory leak due to incorrect CRCs in tEXt chunks + (CVE-2008-6218). We still leak memory on read errors. */ +static int +png_crc_finish_1(png_structp png_ptr, png_uint_32 skip, + void *to_free_on_error) { png_size_t i; png_size_t istop = png_ptr->zbuf_size; @@ -175,6 +173,7 @@ png_crc_finish(png_structp png_ptr, png_ } else { + png_free(png_ptr, to_free_on_error); png_chunk_error(png_ptr, "CRC error"); } return (1); @@ -183,6 +182,16 @@ png_crc_finish(png_structp png_ptr, png_ return (0); } +/* Optionally skip data and then check the CRC. Depending on whether we + are reading a ancillary or critical chunk, and how the program has set + things up, we may calculate the CRC on the data and print a message. + Returns '1' if there was a CRC error, '0' otherwise. */ +int /* PRIVATE */ +png_crc_finish(png_structp png_ptr, png_uint_32 skip) +{ + return png_crc_finish_1(png_ptr, skip, 0); +} + /* Compare the CRC stored in the PNG file with that calculated by libpng from * the data it has read thus far. */ @@ -2036,7 +2045,7 @@ png_handle_tEXt(png_structp png_ptr, png slength = (png_size_t)length; png_crc_read(png_ptr, (png_bytep)png_ptr->chunkdata, slength); - if (png_crc_finish(png_ptr, skip)) + if (png_crc_finish_1(png_ptr, skip, key)) { png_free(png_ptr, png_ptr->chunkdata); png_ptr->chunkdata = NULL;