aboutsummaryrefslogtreecommitdiffhomepage
path: root/projects/libpng
diff options
context:
space:
mode:
Diffstat (limited to 'projects/libpng')
-rw-r--r--projects/libpng/Dockerfile23
-rwxr-xr-xprojects/libpng/build.sh33
-rw-r--r--projects/libpng/libpng_read_fuzzer.cc123
-rw-r--r--projects/libpng/libpng_read_fuzzer.options2
-rw-r--r--projects/libpng/png.dict38
-rw-r--r--projects/libpng/target.yaml1
6 files changed, 220 insertions, 0 deletions
diff --git a/projects/libpng/Dockerfile b/projects/libpng/Dockerfile
new file mode 100644
index 00000000..04a73b8a
--- /dev/null
+++ b/projects/libpng/Dockerfile
@@ -0,0 +1,23 @@
+# Copyright 2016 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+FROM ossfuzz/base-libfuzzer
+MAINTAINER mmoroz@chromium.org
+RUN apt-get install -y make autoconf automake libtool zlib1g-dev
+
+RUN git clone git://git.code.sf.net/p/libpng/code libpng
+WORKDIR libpng
+COPY build.sh libpng_read_fuzzer.* png.dict $SRC/
diff --git a/projects/libpng/build.sh b/projects/libpng/build.sh
new file mode 100755
index 00000000..a5d4760f
--- /dev/null
+++ b/projects/libpng/build.sh
@@ -0,0 +1,33 @@
+#!/bin/bash -eu
+# Copyright 2016 Google Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+################################################################################
+
+# Disable logging via library build configuration control.
+cat scripts/pnglibconf.dfa | sed -e "s/option STDIO/option STDIO disabled/" \
+> scripts/pnglibconf.dfa.temp
+mv scripts/pnglibconf.dfa.temp scripts/pnglibconf.dfa
+
+# build the library.
+autoreconf -f -i
+./configure
+make -j$(nproc) clean all
+
+# build libpng_read_fuzzer
+$CXX $CXXFLAGS -std=c++11 -I. -lz \
+ $SRC/libpng_read_fuzzer.cc -o $OUT/libpng_read_fuzzer \
+ -lfuzzer .libs/libpng16.a
+
+cp $SRC/*.dict $SRC/*.options $OUT/
diff --git a/projects/libpng/libpng_read_fuzzer.cc b/projects/libpng/libpng_read_fuzzer.cc
new file mode 100644
index 00000000..ca489b09
--- /dev/null
+++ b/projects/libpng/libpng_read_fuzzer.cc
@@ -0,0 +1,123 @@
+// 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 <stddef.h>
+#include <stdint.h>
+
+#include <vector>
+
+#define PNG_INTERNAL
+#include "png.h"
+
+struct BufState {
+ const uint8_t* data;
+ size_t bytes_left;
+};
+
+struct PngObjectHandler {
+ png_infop info_ptr = nullptr;
+ png_structp png_ptr = nullptr;
+ png_voidp row_ptr = nullptr;
+ BufState* buf_state = nullptr;
+
+ ~PngObjectHandler() {
+ if (row_ptr && png_ptr) {
+ png_free(png_ptr, row_ptr);
+ }
+ if (png_ptr && info_ptr) {
+ png_destroy_read_struct(&png_ptr, &info_ptr, nullptr);
+ }
+ delete buf_state;
+ }
+};
+
+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 uint8_t* 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;
+ }
+
+ PngObjectHandler png_handler;
+ png_handler.png_ptr = png_create_read_struct
+ (PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr);
+ if (!png_handler.png_ptr) {
+ return 0;
+ }
+
+ png_set_crc_action(png_handler.png_ptr, PNG_CRC_QUIET_USE, PNG_CRC_QUIET_USE);
+
+ png_handler.info_ptr = png_create_info_struct(png_handler.png_ptr);
+ if (!png_handler.info_ptr) {
+ return 0;
+ }
+
+ // Setting up reading from buffer.
+ png_handler.buf_state = new BufState();
+ png_handler.buf_state->data = data + kPngHeaderSize;
+ png_handler.buf_state->bytes_left = size - kPngHeaderSize;
+ png_set_read_fn(png_handler.png_ptr, png_handler.buf_state, user_read_data);
+ png_set_sig_bytes(png_handler.png_ptr, kPngHeaderSize);
+
+ // libpng error handling.
+ if (setjmp(png_jmpbuf(png_handler.png_ptr))) {
+ return 0;
+ }
+
+ // 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))) {
+ return 0;
+ }
+
+ png_uint_32 width, height;
+ int bit_depth, color_type, interlace_type, compression_type;
+ int filter_type;
+
+ if (!png_get_IHDR(png_handler.png_ptr, png_handler.info_ptr, &width,
+ &height, &bit_depth, &color_type, &interlace_type,
+ &compression_type, &filter_type)) {
+ return 0;
+ }
+
+ // This is going to be too slow.
+ if (width && height > 100000000 / width)
+ return 0;
+
+ int passes = png_set_interlace_handling(png_handler.png_ptr);
+ png_start_read_image(png_handler.png_ptr);
+
+ for (int pass = 0; pass < passes; ++pass) {
+ for (png_uint_32 y = 0; y < height; ++y) {
+ png_read_row(png_handler.png_ptr,
+ static_cast<png_bytep>(png_handler.row_ptr), NULL);
+ }
+ }
+
+ return 0;
+}
diff --git a/projects/libpng/libpng_read_fuzzer.options b/projects/libpng/libpng_read_fuzzer.options
new file mode 100644
index 00000000..2005291a
--- /dev/null
+++ b/projects/libpng/libpng_read_fuzzer.options
@@ -0,0 +1,2 @@
+[libfuzzer]
+dict = png.dict
diff --git a/projects/libpng/png.dict b/projects/libpng/png.dict
new file mode 100644
index 00000000..ea12d19e
--- /dev/null
+++ b/projects/libpng/png.dict
@@ -0,0 +1,38 @@
+#
+# AFL dictionary for PNG images
+# -----------------------------
+#
+# Just the basic, standard-originating sections; does not include vendor
+# extensions.
+#
+# Created by Michal Zalewski <lcamtuf@google.com>
+#
+
+header_png="\x89PNG\x0d\x0a\x1a\x0a"
+
+section_IDAT="IDAT"
+section_IEND="IEND"
+section_IHDR="IHDR"
+section_PLTE="PLTE"
+section_bKGD="bKGD"
+section_cHRM="cHRM"
+section_fRAc="fRAc"
+section_gAMA="gAMA"
+section_gIFg="gIFg"
+section_gIFt="gIFt"
+section_gIFx="gIFx"
+section_hIST="hIST"
+section_iCCP="iCCP"
+section_iTXt="iTXt"
+section_oFFs="oFFs"
+section_pCAL="pCAL"
+section_pHYs="pHYs"
+section_sBIT="sBIT"
+section_sCAL="sCAL"
+section_sPLT="sPLT"
+section_sRGB="sRGB"
+section_sTER="sTER"
+section_tEXt="tEXt"
+section_tIME="tIME"
+section_tRNS="tRNS"
+section_zTXt="zTXt"
diff --git a/projects/libpng/target.yaml b/projects/libpng/target.yaml
new file mode 100644
index 00000000..2f64de3a
--- /dev/null
+++ b/projects/libpng/target.yaml
@@ -0,0 +1 @@
+homepage: "http://www.libpng.org/pub/png/libpng.html"