summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoraizatsky <aizatsky@chromium.org>2016-01-14 17:19:29 -0800
committerCommit bot <commit-bot@chromium.org>2016-01-15 01:21:28 +0000
commit0cdedd8bcb208f66b82b558583df624fd5cd583f (patch)
tree272a56baf3d09fd12b246858a1f6a0c26a0f4a77
parent73f22223aaae7155b6c10792ecdbfd5166e7fe91 (diff)
downloadchromium_src-0cdedd8bcb208f66b82b558583df624fd5cd583f.zip
chromium_src-0cdedd8bcb208f66b82b558583df624fd5cd583f.tar.gz
chromium_src-0cdedd8bcb208f66b82b558583df624fd5cd583f.tar.bz2
[libfuzzer] libpng read fuzzer
BUG=539572 Review URL: https://codereview.chromium.org/1574393007 Cr-Commit-Position: refs/heads/master@{#369646}
-rw-r--r--testing/libfuzzer/fuzzers/BUILD.gn10
-rw-r--r--testing/libfuzzer/fuzzers/libpng_read_fuzzer.cc89
2 files changed, 99 insertions, 0 deletions
diff --git a/testing/libfuzzer/fuzzers/BUILD.gn b/testing/libfuzzer/fuzzers/BUILD.gn
index c809066..8fa3e88 100644
--- a/testing/libfuzzer/fuzzers/BUILD.gn
+++ b/testing/libfuzzer/fuzzers/BUILD.gn
@@ -286,3 +286,13 @@ fuzzer_test("libexif_parser_fuzzer") {
"//third_party/libexif:libexif_fuzzers",
]
}
+
+fuzzer_test("libpng_read_fuzzer") {
+ sources = [
+ "libpng_read_fuzzer.cc",
+ ]
+ deps = [
+ "//base",
+ "//third_party/libpng",
+ ]
+}
diff --git a/testing/libfuzzer/fuzzers/libpng_read_fuzzer.cc b/testing/libfuzzer/fuzzers/libpng_read_fuzzer.cc
new file mode 100644
index 0000000..83c2462
--- /dev/null
+++ b/testing/libfuzzer/fuzzers/libpng_read_fuzzer.cc
@@ -0,0 +1,89 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include <vector>
+
+#include "base/bind.h"
+#include "base/callback_helpers.h"
+#include "third_party/libpng/png.h"
+
+struct BufState {
+ const unsigned char *data;
+ size_t bytes_left;
+};
+
+void user_read_data(png_structp png_ptr, png_bytep data, png_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");
+ }
+ memcpy(data, buf_state->data, length);
+ buf_state->bytes_left -= length;
+ buf_state->data += length;
+}
+static const int kPngHeaderSize = 8;
+
+// Entry point for LibFuzzer.
+// Roughly follows the libpng book example:
+// http://www.libpng.org/pub/png/book/chapter13.html
+extern "C" int LLVMFuzzerTestOneInput(const unsigned char *data, size_t size) {
+ if (size < kPngHeaderSize) {
+ return 0;
+ }
+
+ std::vector<unsigned char> v(data, data + size);
+ if (!png_sig_cmp(v.data(), 0, kPngHeaderSize)) {
+ // not a PNG.
+ return 0;
+ }
+
+ png_structp png_ptr = png_create_read_struct
+ (PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
+ assert(png_ptr);
+
+ png_infop info_ptr = png_create_info_struct(png_ptr);
+ assert(info_ptr);
+
+ base::ScopedClosureRunner struct_deleter(base::Bind(
+ &png_destroy_read_struct, &png_ptr, &info_ptr, nullptr));
+
+ if (setjmp(png_ptr->jmpbuf)) {
+ // error handling for libpng
+ return 0;
+ }
+
+ // Setting up reading from buffer.
+ std::unique_ptr<BufState> buf_state(new BufState());
+ buf_state->data = data + kPngHeaderSize;
+ buf_state->bytes_left = size - kPngHeaderSize;
+ png_set_read_fn(png_ptr, buf_state.get(), user_read_data);
+ png_set_sig_bytes(png_ptr, kPngHeaderSize);
+
+ // Reading
+ png_read_info(png_ptr, info_ptr);
+ png_voidp row = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr));
+ base::ScopedClosureRunner png_deleter(base::Bind(
+ &png_free, png_ptr, row));
+
+ png_uint_32 width, height;
+ int bit_depth, color_type, interlace_type, compression_type;
+ int filter_type;
+
+ if (!png_get_IHDR(png_ptr, info_ptr, &width, &height,
+ &bit_depth, &color_type, &interlace_type,
+ &compression_type, &filter_type)) {
+ return 0;
+ }
+
+ int passes = png_set_interlace_handling(png_ptr);
+ png_start_read_image(png_ptr);
+
+ for (int pass = 0; pass < passes; ++pass) {
+ for (png_uint_32 y = 0; y < height; ++y) {
+ png_read_row(png_ptr, static_cast<png_bytep>(row), NULL);
+ }
+ }
+
+ return 0;
+}