From afa38abb0ce1f95aad36f8ccd02eac622352f25a Mon Sep 17 00:00:00 2001 From: Jonathan Rudenberg Date: Thu, 18 Jan 2018 10:45:09 -0500 Subject: [PATCH] [mupdf] Add mupdf fuzzer (#1067) * Add fuzzer for mupdf * Address review comments * Add check to ensure corpus/dict exist * Silence stderr spam * Update fuzzer based on review comments * Enable MemorySanitizer * Set primary contact --- projects/mupdf/Dockerfile | 27 +++++++++++++++++++ projects/mupdf/build.sh | 40 ++++++++++++++++++++++++++++ projects/mupdf/pdf_fuzzer.cc | 43 +++++++++++++++++++++++++++++++ projects/mupdf/pdf_fuzzer.options | 2 ++ projects/mupdf/project.yaml | 8 ++++++ 5 files changed, 120 insertions(+) create mode 100644 projects/mupdf/Dockerfile create mode 100755 projects/mupdf/build.sh create mode 100644 projects/mupdf/pdf_fuzzer.cc create mode 100644 projects/mupdf/pdf_fuzzer.options create mode 100644 projects/mupdf/project.yaml diff --git a/projects/mupdf/Dockerfile b/projects/mupdf/Dockerfile new file mode 100644 index 000000000..0b0b760fb --- /dev/null +++ b/projects/mupdf/Dockerfile @@ -0,0 +1,27 @@ +# Copyright 2018 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 gcr.io/oss-fuzz-base/base-builder +MAINTAINER jonathan@titanous.com +RUN apt-get update && apt-get install -y make libtool pkg-config +RUN git clone --recursive --depth 1 git://git.ghostscript.com/mupdf.git mupdf +RUN git clone --depth 1 https://github.com/mozilla/pdf.js pdf.js && \ + zip -q $SRC/pdf_fuzzer_seed_corpus.zip pdf.js/test/pdfs/*.pdf && \ + rm -rf pdf.js +ADD https://raw.githubusercontent.com/rc0r/afl-fuzz/master/dictionaries/pdf.dict $SRC/pdf_fuzzer.dict +WORKDIR mupdf +COPY *.cc source/fuzz/ +COPY build.sh *.options $SRC/ diff --git a/projects/mupdf/build.sh b/projects/mupdf/build.sh new file mode 100755 index 000000000..83c1105fb --- /dev/null +++ b/projects/mupdf/build.sh @@ -0,0 +1,40 @@ +#!/bin/bash -eu +# Copyright 2018 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. +# +################################################################################ + +LDFLAGS="$CXXFLAGS" make -j$(nproc) HAVE_GLUT=no build=debug OUT=$WORK +fuzz_target=pdf_fuzzer + +$CXX $CXXFLAGS -std=c++11 -Iinclude \ + source/fuzz/pdf_fuzzer.cc -o $OUT/$fuzz_target \ + -lFuzzingEngine $WORK/libmupdf.a $WORK/libmupdfthird.a + +mv $SRC/{*.zip,*.dict,*.options} $OUT + +if [ ! -f "${OUT}/${fuzz_target}_seed_corpus.zip" ]; then + echo "missing seed corpus" + exit 1 +fi + +if [ ! -f "${OUT}/${fuzz_target}.dict" ]; then + echo "missing dictionary" + exit 1 +fi + +if [ ! -f "${OUT}/${fuzz_target}.options" ]; then + echo "missing options" + exit 1 +fi diff --git a/projects/mupdf/pdf_fuzzer.cc b/projects/mupdf/pdf_fuzzer.cc new file mode 100644 index 000000000..3b1e1f667 --- /dev/null +++ b/projects/mupdf/pdf_fuzzer.cc @@ -0,0 +1,43 @@ +/* +# Copyright 2018 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. +# +################################################################################ +*/ + +#include + +#include + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + fz_context *ctx = fz_new_context(nullptr, nullptr, FZ_STORE_DEFAULT); + + fz_stream *stream = fz_open_memory(ctx, data, size); + fz_matrix ctm; + fz_pixmap *pix; + fz_try(ctx) { + fz_document *doc = fz_open_document_with_stream(ctx, "pdf", stream); + for (int i = 0; i < fz_count_pages(ctx, doc); i++) { + pix = fz_new_pixmap_from_page_number(ctx, doc, i, &ctm, fz_device_rgb(ctx), 0); + fz_drop_pixmap(ctx, pix); + } + fz_drop_document(ctx, doc); + } + fz_catch(ctx) {} + + fz_drop_stream(ctx, stream); + fz_drop_context(ctx); + + return 0; +} diff --git a/projects/mupdf/pdf_fuzzer.options b/projects/mupdf/pdf_fuzzer.options new file mode 100644 index 000000000..329a6e27b --- /dev/null +++ b/projects/mupdf/pdf_fuzzer.options @@ -0,0 +1,2 @@ +[libfuzzer] +close_fd_mask = 3 diff --git a/projects/mupdf/project.yaml b/projects/mupdf/project.yaml new file mode 100644 index 000000000..9009fc291 --- /dev/null +++ b/projects/mupdf/project.yaml @@ -0,0 +1,8 @@ +homepage: "https://www.mupdf.com" +primary_contact: tor.andersson@artifex.com +sanitizers: + - address + - undefined + - memory +auto_ccs: + - jonathan@titanous.com