[libpng16] Stop memory leak when returning from png_handle_eXIf() with an error

(Bug report from the OSS-fuzz project).
This commit is contained in:
Glenn Randers-Pehrson 2017-08-01 21:42:16 -05:00
parent cb628b2e4e
commit 71a56180e5
6 changed files with 50 additions and 21 deletions

View File

@ -1,4 +1,4 @@
Libpng 1.6.32beta03 - August 1, 2017 Libpng 1.6.32beta03 - August 2, 2017
This is not intended to be a public release. It will be replaced This is not intended to be a public release. It will be replaced
within a few weeks by a public version or by another test version. within a few weeks by a public version or by another test version.
@ -39,9 +39,10 @@ Version 1.6.32beta01 [July 31, 2017]
Version 1.6.32beta02 [August 1, 2017] Version 1.6.32beta02 [August 1, 2017]
Updated contrib/libtests/pngunknown.c with eXIf chunk. Updated contrib/libtests/pngunknown.c with eXIf chunk.
Version 1.6.32beta03 [August 1, 2017] Version 1.6.32beta03 [August 2, 2017]
Initialized btoa[] in pngstest.c Initialized btoa[] in pngstest.c
Stop memory leak when returning from png_handle_eXIf() with an error. Stop memory leak when returning from png_handle_eXIf() with an error
(Bug report from the OSS-fuzz project).
Send comments/corrections/commendations to png-mng-implement at lists.sf.net Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit (subscription required; visit

View File

@ -5919,12 +5919,13 @@ Version 1.6.32beta01 [July 31, 2017]
png_set_eXIf_1(), respectively, to avoid breaking API compatibility png_set_eXIf_1(), respectively, to avoid breaking API compatibility
with libpng-1.6.31. with libpng-1.6.31.
Version 1.6.32beta02 [August 1, 2017] Version 1.6.32beta02 [August 2, 2017]
Updated contrib/libtests/pngunknown.c with eXIf chunk. Updated contrib/libtests/pngunknown.c with eXIf chunk.
Version 1.6.32beta03 [August 1, 2017] Version 1.6.32beta03 [August 2, 2017]
Initialized btoa[] in pngstest.c Initialized btoa[] in pngstest.c
Stop memory leak when returning from png_handle_eXIf() with an error. Stop memory leak when returning from png_handle_eXIf() with an error
(Bug report from the OSS-fuzz project).
Send comments/corrections/commendations to png-mng-implement at lists.sf.net Send comments/corrections/commendations to png-mng-implement at lists.sf.net
(subscription required; visit (subscription required; visit

View File

@ -186,8 +186,11 @@ defined(PNG_READ_BACKGROUND_SUPPORTED)
#endif #endif
#ifdef PNG_eXIf_SUPPORTED #ifdef PNG_eXIf_SUPPORTED
int num_exif; int num_exif; /* Added at libpng-1.6.31 */
png_bytep exif; png_bytep exif;
# ifdef PNG_READ_eXIf_SUPPORTED
png_bytep eXIf_buf; /* Added at libpng-1.6.32 */
# endif
#endif #endif
#ifdef PNG_hIST_SUPPORTED #ifdef PNG_hIST_SUPPORTED

View File

@ -2014,6 +2014,7 @@ void /* PRIVATE */
png_handle_eXIf(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length) png_handle_eXIf(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
{ {
unsigned int i; unsigned int i;
png_bytep eXIf_buf; png_bytep eXIf_buf;
png_debug(1, "in png_handle_eXIf"); png_debug(1, "in png_handle_eXIf");
@ -2031,18 +2032,25 @@ png_handle_eXIf(png_structrp png_ptr, png_inforp info_ptr, png_uint_32 length)
eXIf_buf = png_voidcast(png_bytep, eXIf_buf = png_voidcast(png_bytep,
png_malloc_warn(png_ptr, length)); png_malloc_warn(png_ptr, length));
if (eXIf_buf == NULL)
{
png_crc_finish(png_ptr, length);
png_chunk_benign_error(png_ptr, "out of memory");
return;
}
info_ptr->eXIf_buf = eXIf_buf; /* So it will be freed on error */
info_ptr->free_me |= PNG_FREE_EXIF;
for (i = 0; i < length; i++) for (i = 0; i < length; i++)
{ {
png_byte buf[1]; png_byte buf[1];
png_crc_read(png_ptr, buf, 1); png_crc_read(png_ptr, buf, 1);
eXIf_buf[i] = buf[0]; eXIf_buf[i] = buf[0];
} }
info_ptr->eXIf_buf = NULL;
if (png_crc_finish(png_ptr, 0) != 0) if (png_crc_finish(png_ptr, 0) != 0)
{
png_free(png_ptr, eXIf_buf);
return; return;
}
png_set_eXIf_1(png_ptr, info_ptr, length, eXIf_buf); png_set_eXIf_1(png_ptr, info_ptr, length, eXIf_buf);

View File

@ -146,7 +146,11 @@ png_set_eXIf_1(png_const_structrp png_ptr, png_inforp info_ptr,
if (png_ptr == NULL || info_ptr == NULL) if (png_ptr == NULL || info_ptr == NULL)
return; return;
png_free_data(png_ptr, info_ptr, PNG_FREE_EXIF, 0); if (info_ptr->exif)
{
png_free(png_ptr, info_ptr->exif);
info_ptr->exif = NULL;
}
info_ptr->num_exif = num_exif; info_ptr->num_exif = num_exif;

View File

@ -936,8 +936,12 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname); fprintf(STDERR, "%s -> %s: libpng read error\n", inname, outname);
png_free(read_ptr, row_buf); png_free(read_ptr, row_buf);
row_buf = NULL; row_buf = NULL;
if (verbose != 0)
fprintf(STDERR, " destroy read structs\n");
png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
#ifdef PNG_WRITE_SUPPORTED #ifdef PNG_WRITE_SUPPORTED
if (verbose != 0)
fprintf(STDERR, " destroy write structs\n");
png_destroy_info_struct(write_ptr, &write_end_info_ptr); png_destroy_info_struct(write_ptr, &write_end_info_ptr);
png_destroy_write_struct(&write_ptr, &write_info_ptr); png_destroy_write_struct(&write_ptr, &write_info_ptr);
#endif #endif
@ -952,11 +956,13 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
if (setjmp(png_jmpbuf(write_ptr))) if (setjmp(png_jmpbuf(write_ptr)))
{ {
fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname); fprintf(STDERR, "%s -> %s: libpng write error\n", inname, outname);
if (verbose != 0)
fprintf(STDERR, " destroying read structs\n");
png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr); png_destroy_read_struct(&read_ptr, &read_info_ptr, &end_info_ptr);
if (verbose != 0)
fprintf(STDERR, " destroying write structs\n");
png_destroy_info_struct(write_ptr, &write_end_info_ptr); png_destroy_info_struct(write_ptr, &write_end_info_ptr);
#ifdef PNG_WRITE_SUPPORTED
png_destroy_write_struct(&write_ptr, &write_info_ptr); png_destroy_write_struct(&write_ptr, &write_info_ptr);
#endif
FCLOSE(fpin); FCLOSE(fpin);
FCLOSE(fpout); FCLOSE(fpout);
return (1); return (1);
@ -1192,16 +1198,19 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
} }
} }
#endif #endif
#ifdef PNG_eXIf_SUPPORTED #ifdef PNG_READ_eXIf_SUPPORTED
{ {
png_bytep exif; png_bytep exif=NULL;
png_uint_32 exif_length; png_uint_32 exif_length;
if (png_get_eXIf_1(read_ptr, read_info_ptr, &exif_length, &exif) != 0) if (png_get_eXIf_1(read_ptr, read_info_ptr, &exif_length, &exif) != 0)
{ {
printf(" eXIf type %c%c, %d bytes\n",exif[0],exif[1], if (exif_length > 1)
(int)exif_length); printf(" eXIf type %c%c, %d bytes\n",exif[0],exif[1],
(int)exif_length);
# ifdef PNG_WRITE_eXIf_SUPPORTED
png_set_eXIf_1(write_ptr, write_info_ptr, exif_length, exif); png_set_eXIf_1(write_ptr, write_info_ptr, exif_length, exif);
# endif
} }
} }
#endif #endif
@ -1547,16 +1556,19 @@ test_one_file(PNG_CONST char *inname, PNG_CONST char *outname)
} }
} }
#endif #endif
#ifdef PNG_eXIf_SUPPORTED #ifdef PNG_READ_eXIf_SUPPORTED
{ {
png_bytep exif; png_bytep exif=NULL;
png_uint_32 exif_length; png_uint_32 exif_length;
if (png_get_eXIf_1(read_ptr, end_info_ptr, &exif_length, &exif) != 0) if (png_get_eXIf_1(read_ptr, end_info_ptr, &exif_length, &exif) != 0)
{ {
printf(" eXIf type %c%c, %d bytes\n",exif[0],exif[1], if (exif_length > 1)
(int)exif_length); printf(" eXIf type %c%c, %d bytes\n",exif[0],exif[1],
(int)exif_length);
# ifdef PNG_WRITE_eXIf_SUPPORTED
png_set_eXIf_1(write_ptr, write_end_info_ptr, exif_length, exif); png_set_eXIf_1(write_ptr, write_end_info_ptr, exif_length, exif);
# endif
} }
} }
#endif #endif