From 414de980470708241bb464c2eccc29bd75343139 Mon Sep 17 00:00:00 2001 From: Glenn Randers-Pehrson Date: Thu, 28 Sep 2017 09:18:47 -0500 Subject: [PATCH] [libpng16] Add end_info structure to libpng fuzzer; add row_ptr to CLEANUP --- contrib/oss-fuzz/libpng_read_fuzzer.cc | 50 +++++++++++++++++++------- 1 file changed, 38 insertions(+), 12 deletions(-) diff --git a/contrib/oss-fuzz/libpng_read_fuzzer.cc b/contrib/oss-fuzz/libpng_read_fuzzer.cc index c1b16249d..78c7c9ff0 100644 --- a/contrib/oss-fuzz/libpng_read_fuzzer.cc +++ b/contrib/oss-fuzz/libpng_read_fuzzer.cc @@ -12,6 +12,7 @@ // 2. setting the option to ignore ADLER32 checksums, // 3. adding "#include " which is needed on some platforms // to provide memcpy(). +// 4. adding read_end_info() and creating an end_info structure. #include #include @@ -23,14 +24,23 @@ #include "png.h" #define PNG_CLEANUP \ - if(png_handler.png_ptr) \ - { \ - if (png_handler.info_ptr) \ - png_destroy_read_struct(&png_handler.png_ptr, &png_handler.info_ptr,\ - nullptr); \ - else \ - png_destroy_read_struct(&png_handler.png_ptr, nullptr, nullptr); \ - } + if(png_handler.png_ptr) \ + { \ + if (png_handler.row_ptr) \ + png_free(png_handler.png_ptr, png_handler.row_ptr); \ + if (png_handler.end_info_ptr) \ + png_destroy_read_struct(&png_handler.png_ptr, &png_handler.info_ptr,\ + &png_handler.end_info_ptr); \ + else if (png_handler.info_ptr) \ + png_destroy_read_struct(&png_handler.png_ptr, &png_handler.info_ptr,\ + nullptr); \ + else \ + png_destroy_read_struct(&png_handler.png_ptr, nullptr, nullptr); \ + png_handler.png_ptr = nullptr; \ + png_handler.row_ptr = nullptr; \ + png_handler.info_ptr = nullptr; \ + png_handler.end_info_ptr = nullptr; \ + } struct BufState { const uint8_t* data; @@ -40,16 +50,19 @@ struct BufState { struct PngObjectHandler { png_infop info_ptr = nullptr; png_structp png_ptr = nullptr; + png_infop end_info_ptr = nullptr; png_voidp row_ptr = nullptr; BufState* buf_state = nullptr; ~PngObjectHandler() { - if (row_ptr && png_ptr) { + if (row_ptr) png_free(png_ptr, row_ptr); - } - if (png_ptr && info_ptr) { + if (end_info_ptr) + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info_ptr); + else if (info_ptr) png_destroy_read_struct(&png_ptr, &info_ptr, nullptr); - } + else + png_destroy_read_struct(&png_ptr, nullptr, nullptr); delete buf_state; } }; @@ -81,6 +94,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } PngObjectHandler png_handler; + png_handler.png_ptr = nullptr; + png_handler.row_ptr = nullptr; + png_handler.info_ptr = nullptr; + png_handler.end_info_ptr = nullptr; + png_handler.png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); if (!png_handler.png_ptr) { @@ -93,6 +111,12 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return 0; } + png_handler.end_info_ptr = png_create_info_struct(png_handler.png_ptr); + if (!png_handler.end_info_ptr) { + PNG_CLEANUP + return 0; + } + png_set_crc_action(png_handler.png_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE); #ifdef PNG_IGNORE_ADLER32 png_set_option(png_handler.png_ptr, PNG_IGNORE_ADLER32, PNG_OPTION_ON); @@ -149,6 +173,8 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { } } + png_read_end(png_handler.png_ptr, png_handler.end_info_ptr); + PNG_CLEANUP return 0; }