diff options
author | Android Build Coastguard Worker <android-build-coastguard-worker@google.com> | 2024-03-22 18:31:46 +0000 |
---|---|---|
committer | Gerrit Code Review <noreply-gerritcodereview@google.com> | 2024-03-22 18:31:46 +0000 |
commit | 945297e8e4ba57bd463a654c83b3e2aef04c9c2a (patch) | |
tree | ee1f53361d29c32f760a8aeed29bf7a966ea89cf /contrib/oss-fuzz/libpng_read_fuzzer.cc | |
parent | 5d19b1bb0f5694f2ae47b3cc2ccfeb571764b439 (diff) | |
parent | 7f2442bc0587522c6a8de11372ff60b64bb06e28 (diff) | |
download | libpng-945297e8e4ba57bd463a654c83b3e2aef04c9c2a.tar.gz |
Merge "Snap for 11612745 from 6cc454b6e9367825dfc9d3f230a6bb5337b1cb3b to emu-35-1-release" into emu-35-1-releaseemu-35-1-release
Diffstat (limited to 'contrib/oss-fuzz/libpng_read_fuzzer.cc')
-rw-r--r-- | contrib/oss-fuzz/libpng_read_fuzzer.cc | 46 |
1 files changed, 37 insertions, 9 deletions
diff --git a/contrib/oss-fuzz/libpng_read_fuzzer.cc b/contrib/oss-fuzz/libpng_read_fuzzer.cc index 78c7c9ff0..0190cf786 100644 --- a/contrib/oss-fuzz/libpng_read_fuzzer.cc +++ b/contrib/oss-fuzz/libpng_read_fuzzer.cc @@ -1,21 +1,21 @@ // libpng_read_fuzzer.cc -// Copyright 2017 Glenn Randers-Pehrson +// Copyright 2017-2018 Glenn Randers-Pehrson // Copyright 2015 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that may // be found in the LICENSE file https://cs.chromium.org/chromium/src/LICENSE -// Last changed in libpng 1.6.32 [August 24, 2017] - // The modifications in 2017 by Glenn Randers-Pehrson include // 1. addition of a PNG_CLEANUP macro, // 2. setting the option to ignore ADLER32 checksums, // 3. adding "#include <string.h>" which is needed on some platforms // to provide memcpy(). // 4. adding read_end_info() and creating an end_info structure. +// 5. adding calls to png_set_*() transforms commonly used by browsers. #include <stddef.h> #include <stdint.h> +#include <stdlib.h> #include <string.h> #include <vector> @@ -59,7 +59,7 @@ struct PngObjectHandler { png_free(png_ptr, row_ptr); if (end_info_ptr) png_destroy_read_struct(&png_ptr, &info_ptr, &end_info_ptr); - else if (info_ptr) + else if (info_ptr) png_destroy_read_struct(&png_ptr, &info_ptr, nullptr); else png_destroy_read_struct(&png_ptr, nullptr, nullptr); @@ -67,7 +67,7 @@ struct PngObjectHandler { } }; -void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length) { +void user_read_data(png_structp png_ptr, png_bytep data, size_t length) { BufState* buf_state = static_cast<BufState*>(png_get_io_ptr(png_ptr)); if (length > buf_state->bytes_left) { png_error(png_ptr, "read error"); @@ -77,6 +77,22 @@ void user_read_data(png_structp png_ptr, png_bytep data, png_size_t length) { buf_state->data += length; } +void* limited_malloc(png_structp, png_alloc_size_t size) { + // libpng may allocate large amounts of memory that the fuzzer reports as + // an error. In order to silence these errors, make libpng fail when trying + // to allocate a large amount. This allocator used to be in the Chromium + // version of this fuzzer. + // This number is chosen to match the default png_user_chunk_malloc_max. + if (size > 8000000) + return nullptr; + + return malloc(size); +} + +void default_free(png_structp, png_voidp ptr) { + return free(ptr); +} + static const int kPngHeaderSize = 8; // Entry point for LibFuzzer. @@ -117,6 +133,9 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return 0; } + // Use a custom allocator that fails for large allocations to avoid OOM. + png_set_mem_fn(png_handler.png_ptr, nullptr, limited_malloc, default_free); + 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); @@ -136,9 +155,6 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { // Reading. png_read_info(png_handler.png_ptr, png_handler.info_ptr); - png_handler.row_ptr = png_malloc( - png_handler.png_ptr, png_get_rowbytes(png_handler.png_ptr, - png_handler.info_ptr)); // reset error handler to put png_deleter into scope. if (setjmp(png_jmpbuf(png_handler.png_ptr))) { @@ -163,8 +179,20 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { return 0; } + // Set several transforms that browsers typically use: + png_set_gray_to_rgb(png_handler.png_ptr); + png_set_expand(png_handler.png_ptr); + png_set_packing(png_handler.png_ptr); + png_set_scale_16(png_handler.png_ptr); + png_set_tRNS_to_alpha(png_handler.png_ptr); + int passes = png_set_interlace_handling(png_handler.png_ptr); - png_start_read_image(png_handler.png_ptr); + + png_read_update_info(png_handler.png_ptr, png_handler.info_ptr); + + png_handler.row_ptr = png_malloc( + png_handler.png_ptr, png_get_rowbytes(png_handler.png_ptr, + png_handler.info_ptr)); for (int pass = 0; pass < passes; ++pass) { for (png_uint_32 y = 0; y < height; ++y) { |