Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
oss-fuzz initial integration
  • Loading branch information
jberkenbilt committed Jun 13, 2019
1 parent d263a04 commit 3d03024
Show file tree
Hide file tree
Showing 19 changed files with 1,694 additions and 2 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -13,6 +13,7 @@ doc/qpdf.1
doc/zlib-flate.1
examples/build/
external-libs
fuzz/build/
libqpdf.map
libqpdf.pc
libqpdf/build/
Expand Down
7 changes: 7 additions & 0 deletions ChangeLog
@@ -1,3 +1,10 @@
2019-06-13 Jay Berkenbilt <ejb@ql.org>

* Perform initial integration of Google's oss-fuzz project by
copying the fuzzer someone from Google already did into the qpdf
repository and adding build support. This shift in control is in
preparation for an ideal integration with oss-fuzz.

2019-06-09 Jay Berkenbilt <ejb@ql.org>

* When /DecodeParms is an empty list, ignore it on read and delete
Expand Down
2 changes: 1 addition & 1 deletion Makefile
Expand Up @@ -35,7 +35,7 @@
# install to install in a separate location. This is useful for
# packagers.

BUILD_ITEMS := manual libqpdf zlib-flate libtests qpdf examples
BUILD_ITEMS := manual libqpdf zlib-flate libtests qpdf fuzz examples
OUTPUT_DIR = build
ALL_TARGETS =

Expand Down
2 changes: 2 additions & 0 deletions NOTICE.md
Expand Up @@ -10,6 +10,8 @@ Versions of qpdf prior to version 7 were released under the terms of version 2.0

The qpdf distribution includes a copy of [qtest](http://qtest.qbilt.org), which is released under the terms of the [version 2.0 of the Artistic license](https://opensource.org/licenses/Artistic-2.0), which can be found at https://opensource.org/licenses/Artistic-2.0.

The standalone fuzz target runner (fuzz/standalone_fuzz_target_runner.cc) is copyright 2017 by Google and is also released under the Apache license, Version 2.0.

The Rijndael encryption implementation used as the basis for AES encryption and decryption support comes from Philip J. Erdelsky's public domain implementation. The files `libqpdf/rijndael.cc` and `libqpdf/qpdf/rijndael.h` remain in the public domain. They were obtained from
* http://www.efgh.com/software/rijndael.htm
* http://www.efgh.com/software/rijndael.txt
Expand Down
13 changes: 13 additions & 0 deletions README-maintainer
Expand Up @@ -17,6 +17,19 @@ Memory checks:
LDFLAGS="-fsanitize=address -fsanitize=undefined" \
--enable-werror --disable-shared

GOOGLE OSS-FUZZ

* https://github.com/google/oss-fuzz/tree/master/projects/qpdf
* To test locally, see https://github.com/google/oss-fuzz/tree/master/docs/,
especially new_project_guide.md

Clone the oss-fuzz project. From the root directory of the repository:

python infra/helper.py build_image --pull qpdf
python infra/helper.py build_fuzzers qpdf
python infra/helper.py check_build qpdf
python infra/helper.py build_fuzzers --sanitizer coverage qpdf
python infra/helper.py coverage qpdf

CODING RULES

Expand Down
1 change: 1 addition & 0 deletions autoconf.mk.in
Expand Up @@ -37,6 +37,7 @@ XMLLINT=@XMLLINT@
BUILD_HTML=@BUILD_HTML@
BUILD_PDF=@BUILD_PDF@
VALIDATE_DOC=@VALIDATE_DOC@
OSS_FUZZ=@OSS_FUZZ@
QPDF_SKIP_TEST_COMPARE_IMAGES=@QPDF_SKIP_TEST_COMPARE_IMAGES@
BUILDRULES=@BUILDRULES@
HAVE_LD_VERSION_SCRIPT=@HAVE_LD_VERSION_SCRIPT@
Expand Down
2 changes: 1 addition & 1 deletion autofiles.sums
@@ -1,4 +1,4 @@
ba2adf968b787efe32cd4396a5cfeceeb52d2c48686bdc21a3b03edae169632c configure.ac
f0057d67ba676a48d07264f6c9a947c59c36dee48dbd6c41903d5f03c586a9cf configure.ac
35bc5c645dc42d47f2daeea06f8f3e767c8a1aee6a35eb2b4854fd2ce66c3413 m4/ax_random_device.m4
37f8897d5f68d7d484e5457832a8f190ddb7507fa2a467cb7ee2be40a4364643 m4/libtool.m4
e77ebba8361b36f14b4d0927173a034b98c5d05049697a9ded84d85eb99a7990 m4/ltoptions.m4
Expand Down
8 changes: 8 additions & 0 deletions azure-pipelines.yml
Expand Up @@ -100,3 +100,11 @@ jobs:
buildPlatform: AppImage
dependsOn: Linux
condition: succeeded()
- job: Fuzzers
pool:
vmImage: ubuntu-16.04
steps:
- script: azure-pipelines/build-fuzzer
displayName: 'Build Fuzzer'
dependsOn: Linux
condition: succeeded()
11 changes: 11 additions & 0 deletions azure-pipelines/build-fuzzer
@@ -0,0 +1,11 @@
#!/bin/bash
set -ex
export WORK=$PWD/work
export OUT=$PWD/out
mkdir -p $WORK $OUT
sudo apt-get update
sudo apt-get -y install \
autoconf build-essential zlib1g-dev libjpeg-dev
./fuzz/oss-fuzz-build
ls -l out/qpdf*fuzzer
ls -l out/
17 changes: 17 additions & 0 deletions configure
Expand Up @@ -630,6 +630,7 @@ ac_includes_default="\

ac_subst_vars='LTLIBOBJS
LIBOBJS
OSS_FUZZ
VALIDATE_DOC
BUILD_PDF
BUILD_HTML
Expand Down Expand Up @@ -774,6 +775,7 @@ enable_doc_maintenance
enable_html_doc
enable_pdf_doc
enable_validate_doc
enable_oss_fuzz
'
ac_precious_vars='build_alias
host_alias
Expand Down Expand Up @@ -1449,6 +1451,8 @@ Optional Features:
--enable-html-doc whether to build HTML documents
--enable-pdf-doc whether to build PDF documents
--enable-validate-doc whether to validate xml document source
--enable-doc-maintenance
if set, build static fuzzers for oss-fuzz

Optional Packages:
--with-PACKAGE[=ARG] use PACKAGE [ARG=yes]
Expand Down Expand Up @@ -16924,6 +16928,19 @@ else
fi



# Check whether --enable-oss-fuzz was given.
if test "${enable_oss_fuzz+set}" = set; then :
enableval=$enable_oss_fuzz; if test "$enableval" = "yes"; then
OSS_FUZZ=1;
else
OSS_FUZZ=0;
fi
else
OSS_FUZZ=0
fi


if test "$VALIDATE_DOC" = "1"; then
if test "$XMLLINT" = ""; then
MISSING_XMLLINT=1
Expand Down
11 changes: 11 additions & 0 deletions configure.ac
Expand Up @@ -501,6 +501,17 @@ AC_ARG_ENABLE(validate-doc,
fi],
[VALIDATE_DOC=$doc_default])

AC_SUBST(OSS_FUZZ)
AC_ARG_ENABLE(oss-fuzz,
AS_HELP_STRING([--enable-doc-maintenance],
[if set, build static fuzzers for oss-fuzz]),
[if test "$enableval" = "yes"; then
OSS_FUZZ=1;
else
OSS_FUZZ=0;
fi],
[OSS_FUZZ=0])

if test "$VALIDATE_DOC" = "1"; then
if test "$XMLLINT" = ""; then
MISSING_XMLLINT=1
Expand Down
1 change: 1 addition & 0 deletions fuzz/Makefile
@@ -0,0 +1 @@
include ../make/proxy.mk
1 change: 1 addition & 0 deletions fuzz/README.md
@@ -0,0 +1 @@
pdf.dict was copied from https://raw.githubusercontent.com/rc0r/afl-fuzz/master/dictionaries/pdf.dict
82 changes: 82 additions & 0 deletions fuzz/build.mk
@@ -0,0 +1,82 @@
# This directory contains support for Google's oss-fuzz project. See
# https://github.com/google/oss-fuzz/tree/master/projects/qpdf

FUZZERS = \
qpdf_read_memory_fuzzer

DEFAULT_FUZZ_RUNNER := standalone_fuzz_target_runner
OBJ_DEFAULT_FUZZ := fuzz/$(OUTPUT_DIR)/$(DEFAULT_FUZZ_RUNNER).$(OBJ)

BINS_fuzz = $(foreach B,$(FUZZERS),fuzz/$(OUTPUT_DIR)/$(call binname,$(B)))
TARGETS_fuzz = $(OBJ_DEFAULT_FUZZ) $(BINS_fuzz)

INCLUDES_fuzz = include

# LIB_FUZZING_ENGINE is overridden by oss-fuzz
LIB_FUZZING_ENGINE ?= $(OBJ_DEFAULT_FUZZ)

# Depend on OBJ_DEFAULT_FUZZ to ensure that it is always compiled.
# Don't depend on LIB_FUZZING_ENGINE, which we can't build. When used
# by oss-fuzz, it will be there.
$(BINS_fuzz): $(TARGETS_libqpdf) $(OBJ_DEFAULT_FUZZ)

# -----

$(foreach B,$(FUZZERS),$(eval \
OBJS_$(B) = $(call src_to_obj,fuzz/$(B).cc)))

ifeq ($(GENDEPS),1)
-include $(foreach B,$(FUZZERS),$(call obj_to_dep,$(OBJS_$(B))))
endif

$(foreach B,$(DEFAULT_FUZZ_RUNNER),$(eval \
fuzz/$(OUTPUT_DIR)/%.$(OBJ): fuzz/$(B).cc ; \
$(call compile,fuzz/$(B).cc,$(INCLUDES_fuzz))))

$(foreach B,$(FUZZERS),$(eval \
$(OBJS_$(B)): fuzz/$(OUTPUT_DIR)/%.$(OBJ): fuzz/$(B).cc ; \
$(call compile,fuzz/$(B).cc,$(INCLUDES_fuzz))))

ifeq ($(suffix $(LIB_FUZZING_ENGINE)),.$(OBJ))
FUZZ_as_obj := $(LIB_FUZZING_ENGINE)
FUZZ_as_lib :=
else
FUZZ_as_obj :=
FUZZ_as_lib := $(LIB_FUZZING_ENGINE)
endif

$(foreach B,$(FUZZERS),$(eval \
fuzz/$(OUTPUT_DIR)/$(call binname,$(B)): $(OBJS_$(B)) ; \
$(call makebin,$(OBJS_$(B)) $(FUZZ_as_obj),$$@,$(LDFLAGS_libqpdf) $(LDFLAGS),$(FUZZ_as_lib) $(LIBS_libqpdf) $(LIBS))))

ifeq ($(OSS_FUZZ),1)

# Build fuzzers linked with static libraries and installed into a
# location provided by oss-fuzz. This is specifically to support the
# oss-fuzz project. These rules won't on systems that don't allow main
# to be in a library or don't name their libraries libsomething.a.

STATIC_BINS_fuzz := $(foreach B,$(FUZZERS),fuzz/$(OUTPUT_DIR)/static/$(call binname,$(B)))
$(STATIC_BINS_fuzz): $(TARGETS_libqpdf) $(OBJ_DEFAULT_FUZZ)

# OUT is provided in the oss-fuzz environment
OUT ?= $(CURDIR)/fuzz/$(OUTPUT_DIR)/fuzz-install

# These are not fully static, but they statically link with qpdf and
# our external dependencies other than system libraries.
$(foreach B,$(FUZZERS),$(eval \
fuzz/$(OUTPUT_DIR)/static/$(call binname,$(B)): $(OBJS_$(B)) ; \
$(call makebin,$(OBJS_$(B)),$$@,$(LDFLAGS_libqpdf) $(LDFLAGS),$(LIB_FUZZING_ENGINE) $(patsubst -l%,-l:lib%.a,$(LIBS_libqpdf) $(LIBS)))))

# The install_fuzz target is used by build.sh in oss-fuzz's qpdf project.
install_fuzz: $(STATIC_BINS_fuzz)
mkdir -p $(OUT)
cp fuzz/pdf.dict $(STATIC_BINS_fuzz) $(OUT)/
for B in $(FUZZERS); do \
cp fuzz/options $(OUT)/$${B}.options; \
if test -d fuzz/$${B}_seed_corpus; then \
(cd fuzz/$${B}_seed_corpus; zip -q -r $(OUT)/$${B}_seed_corpus.zip .); \
fi; \
done

endif # OSS_FUZZ
2 changes: 2 additions & 0 deletions fuzz/options
@@ -0,0 +1,2 @@
[libfuzzer]
dict = pdf.dict
18 changes: 18 additions & 0 deletions fuzz/oss-fuzz-build
@@ -0,0 +1,18 @@
#!/bin/bash -e

# This is used invoked from
# https://github.com/google/oss-fuzz/blob/master/projects/qpdf/build.sh

# It should be run from the top level directory of a clean checkout of
# qpdf. It is also exercised in ../azure-pipelines/build-fuzzer

./configure \
--enable-oss-fuzz \
--enable-static \
--disable-shared \
--prefix="$WORK" \
LDFLAGS="-L$WORK/lib" \
CPPFLAGS="-I$WORK/include" \
LIBS="-pthread"
make -j$(nproc) install
make install_fuzz

0 comments on commit 3d03024

Please sign in to comment.