Hi Anibal! attached is a patch I backported from the new upstream release, prepared for an NMU to fix these issues. Feel free to just use the patch itself if you have the time to upload yourself. It will be also archived on: http://people.debian.org/~nion/nmu-diff/libpng-1.2.15~beta5-2_1.2.15~beta5-2.1.patch
Kind regards Nico -- Nico Golde - http://ngolde.de - [EMAIL PROTECTED] - GPG: 0x73647CFF For security reasons, all text in this mail is double-rot13 encrypted.
diff -u libpng-1.2.15~beta5/pngrutil.c libpng-1.2.15~beta5/pngrutil.c --- libpng-1.2.15~beta5/pngrutil.c +++ libpng-1.2.15~beta5/pngrutil.c @@ -282,13 +282,13 @@ char umsg[52]; if (ret == Z_BUF_ERROR) - sprintf(umsg,"Buffer error in compressed datastream in %s chunk", + snprintf(umsg, sizeof(umsg), "Buffer error in compressed datastream in %s chunk", png_ptr->chunk_name); else if (ret == Z_DATA_ERROR) - sprintf(umsg,"Data error in compressed datastream in %s chunk", + snprintf(umsg,sizeof(umsg), "Data error in compressed datastream in %s chunk", png_ptr->chunk_name); else - sprintf(umsg,"Incomplete compressed datastream in %s chunk", + snprintf(umsg,sizeof(umsg), "Incomplete compressed datastream in %s chunk", png_ptr->chunk_name); png_warning(png_ptr, umsg); #else @@ -321,7 +321,7 @@ #if !defined(PNG_NO_STDIO) && !defined(_WIN32_WCE) char umsg[50]; - sprintf(umsg, "Unknown zTXt compression type %d", comp_type); + snprintf(umsg, sizeof(umsg), "Unknown zTXt compression type %d", comp_type); png_warning(png_ptr, umsg); #else png_warning(png_ptr, "Unknown zTXt compression type"); @@ -1037,7 +1037,7 @@ /* there should be at least one zero (the compression type byte) following the separator, and we should be on it */ - if ( profile >= chunkdata + slength) + if ( profile >= chunkdata + slength - 1) { png_free(png_ptr, chunkdata); png_warning(png_ptr, "Malformed iCCP chunk"); @@ -1141,7 +1141,7 @@ ++entry_start; /* a sample depth should follow the separator, and we should be on it */ - if (entry_start > chunkdata + slength) + if (entry_start > chunkdata + slength - 2) { png_free(png_ptr, chunkdata); png_warning(png_ptr, "malformed sPLT chunk"); @@ -1660,7 +1660,7 @@ buf++; /* Skip the null string terminator from previous parameter. */ png_debug1(3, "Reading pCAL parameter %d\n", i); - for (params[i] = buf; *buf != 0x00 && buf <= endptr; buf++) + for (params[i] = buf; buf <= endptr && *buf != 0x00 && buf <= endptr; buf++) /* Empty loop to move past each parameter string */ ; /* Make sure we haven't run out of data yet */ @@ -1758,6 +1758,17 @@ /* empty loop */ ; ep++; + if (buffer + slength < ep) + { + png_warning(png_ptr, "Truncated sCAL chunk"); +#if defined(PNG_FIXED_POINT_SUPPORTED) && \ + !defined(PNG_FLOATING_POINT_SUPPORTED) + png_free(png_ptr, swidth); +#endif + png_free(png_ptr, buffer); + return; + } + #ifdef PNG_FLOATING_POINT_SUPPORTED height = png_strtod(png_ptr, ep, &vp); if (*vp) @@ -1981,10 +1992,11 @@ /* empty loop */ ; /* zTXt must have some text after the chunkdataword */ - if (text == chunkdata + slength) + if (text >= chunkdata + slength - 2) { - comp_type = PNG_TEXT_COMPRESSION_NONE; - png_warning(png_ptr, "Zero length zTXt chunk"); + png_warning(png_ptr, "Truncated zTXt chunk"); + png_free(png_ptr, chunkdata); + return; } else { @@ -2084,7 +2096,7 @@ translated keyword (possibly empty), and possibly some text after the keyword */ - if (lang >= chunkdata + slength) + if (lang >= chunkdata + slength - 3) { comp_flag = PNG_TEXT_COMPRESSION_NONE; png_warning(png_ptr, "Zero length iTXt chunk"); @@ -2099,10 +2111,24 @@ /* empty loop */ ; lang_key++; /* skip NUL separator */ + if (lang_key >= chunkdata + slength) + { + png_warning(png_ptr, "Truncated iTXt chunk"); + png_free(png_ptr, chunkdata); + return; + } + for (text = lang_key; *text; text++) /* empty loop */ ; text++; /* skip NUL separator */ + if (text >= chunkdata + slength) + { + png_warning(png_ptr, "Malformed iTXt chunk"); + png_free(png_ptr, chunkdata); + return; + } + prefix_len = text - chunkdata; key=chunkdata; @@ -2186,30 +2212,36 @@ length = (png_uint_32)65535L; } #endif - png_strcpy((png_charp)chunk.name, (png_charp)png_ptr->chunk_name); + png_strncpy((png_charp)chunk.name, (png_charp)png_ptr->chunk_name, 4); + chunk.name[4] = '\0'; chunk.data = (png_bytep)png_malloc(png_ptr, length); chunk.size = (png_size_t)length; png_crc_read(png_ptr, (png_bytep)chunk.data, length); + #if defined(PNG_READ_USER_CHUNKS_SUPPORTED) if(png_ptr->read_user_chunk_fn != NULL) { /* callback to user unknown chunk handler */ - if ((*(png_ptr->read_user_chunk_fn)) (png_ptr, &chunk) <= 0) + int ret; + ret = (*(png_ptr->read_user_chunk_fn)) (png_ptr, &chunk); + if (ret < 0) + png_chunk_error(png_ptr, "error in user chunk"); + if (ret == 0) { if (!(png_ptr->chunk_name[0] & 0x20)) if(png_handle_as_unknown(png_ptr, png_ptr->chunk_name) != PNG_HANDLE_CHUNK_ALWAYS) - { - png_free(png_ptr, chunk.data); png_chunk_error(png_ptr, "unknown critical chunk"); - } png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1); + } } - else +#else + png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1); + #endif - png_set_unknown_chunks(png_ptr, info_ptr, &chunk, 1); png_free(png_ptr, chunk.data); + chunk.data = NULL; } else #endif @@ -2218,8 +2250,7 @@ png_crc_finish(png_ptr, skip); #if !defined(PNG_READ_USER_CHUNKS_SUPPORTED) - if (&info_ptr == NULL) /* quiet compiler warnings about unused info_ptr */ - return; + info_ptr = info_ptr; /* quiet compiler warnings about unused info_ptr */ #endif } diff -u libpng-1.2.15~beta5/debian/changelog libpng-1.2.15~beta5/debian/changelog --- libpng-1.2.15~beta5/debian/changelog +++ libpng-1.2.15~beta5/debian/changelog @@ -1,3 +1,11 @@ +libpng (1.2.15~beta5-2.1) unstable; urgency=high + + * Non-maintainer upload by testing security team. + * Fixed out-of-bounds read operations triggered by crafted + png image files (CVE-2007-5269) (Closes: #446308). + + -- Nico Golde <[EMAIL PROTECTED]> Sun, 14 Oct 2007 01:12:51 +0200 + libpng (1.2.15~beta5-2) unstable; urgency=high * It seems that a grayscale image with a malformed (bad CRC) tRNS
pgpslvLKrnWsV.pgp
Description: PGP signature