diff --git a/Makefile.am b/Makefile.am index aaf1417d..fb7cb18f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,5 +1,5 @@ EXTRA_DIST = README.md COPYING.LGPL FAQ.md docs misc autogen.sh -SUBDIRS = po tests +SUBDIRS = po tests tests/fuzz CLEANFILES = DISTCLEAN_TARGETS = @@ -18,11 +18,8 @@ AM_CXXFLAGS = -Wall AM_LDFLAGS = if ENABLE_FUZZ_TARGETS -SUBDIRS += tests/fuzz - AM_CFLAGS += -fsanitize=fuzzer-no-link AM_CXXFLAGS += -fsanitize=fuzzer-no-link -AM_LDFLAGS += -fsanitize=fuzzer-no-link endif LDADD = $(LTLIBINTL) diff --git a/configure.ac b/configure.ac index 114bf024..647523ff 100644 --- a/configure.ac +++ b/configure.ac @@ -215,27 +215,16 @@ if test "x$enable_pwquality" = "xyes"; then fi dnl ========================================================================== -dnl libprotobuf-fuzzer library +dnl fuzzers, it requires own static library compilation later AC_ARG_ENABLE([fuzz-targets], AS_HELP_STRING([--enable-fuzz-targets], [enable building fuzz targets])) AM_CONDITIONAL(ENABLE_FUZZ_TARGETS, test "x$enable_fuzz_targets" = "xyes") if test "x$enable_fuzz_targets" = "xyes"; then - if test "x$CC" != "xclang" || test "x$CXX" != "xclang++"; then - AC_MSG_ERROR([Building fuzz targets is only supported using clang. Please set CC=clang CXX=clang++]) - fi - PKG_CHECK_MODULES([PROTOBUF], [protobuf],, - AC_MSG_ERROR([You need protobuf library to build fuzz targets.])) - AC_SUBST([PROTOBUF_LIBS]) - - PKG_CHECK_MODULES([LIBPROTOBUF_MUTATOR], [ libprotobuf-mutator ],, - AC_MSG_ERROR([You need libprotobuf-mutator library to build fuzz targets.])) - AC_SUBST([LIBPROTOBUF_MUTATOR_LIBS]) - AC_SUBST([LIBPROTOBUF_MUTATOR_CFLAGS]) - AC_CONFIG_FILES([tests/fuzz/Makefile]) + AX_CHECK_COMPILE_FLAG([-fsanitize=fuzzer-no-link],, + AC_MSG_ERROR([Required compiler options not supported; use clang.]), [-Werror]) fi - dnl ========================================================================== dnl passwdqc library (cryptsetup CLI only) AC_ARG_ENABLE([passwdqc], @@ -778,5 +767,6 @@ lib/libcryptsetup.pc po/Makefile.in scripts/cryptsetup.conf tests/Makefile +tests/fuzz/Makefile ]) AC_OUTPUT diff --git a/m4/ax_check_compile_flag.m4 b/m4/ax_check_compile_flag.m4 new file mode 100644 index 00000000..bd753b34 --- /dev/null +++ b/m4/ax_check_compile_flag.m4 @@ -0,0 +1,53 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_check_compile_flag.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_CHECK_COMPILE_FLAG(FLAG, [ACTION-SUCCESS], [ACTION-FAILURE], [EXTRA-FLAGS], [INPUT]) +# +# DESCRIPTION +# +# Check whether the given FLAG works with the current language's compiler +# or gives an error. (Warnings, however, are ignored) +# +# ACTION-SUCCESS/ACTION-FAILURE are shell commands to execute on +# success/failure. +# +# If EXTRA-FLAGS is defined, it is added to the current language's default +# flags (e.g. CFLAGS) when the check is done. The check is thus made with +# the flags: "CFLAGS EXTRA-FLAGS FLAG". This can for example be used to +# force the compiler to issue an error when a bad flag is given. +# +# INPUT gives an alternative input source to AC_COMPILE_IFELSE. +# +# NOTE: Implementation based on AX_CFLAGS_GCC_OPTION. Please keep this +# macro in sync with AX_CHECK_{PREPROC,LINK}_FLAG. +# +# LICENSE +# +# Copyright (c) 2008 Guido U. Draheim +# Copyright (c) 2011 Maarten Bosmans +# +# Copying and distribution of this file, with or without modification, are +# permitted in any medium without royalty provided the copyright notice +# and this notice are preserved. This file is offered as-is, without any +# warranty. + +#serial 6 + +AC_DEFUN([AX_CHECK_COMPILE_FLAG], +[AC_PREREQ(2.64)dnl for _AC_LANG_PREFIX and AS_VAR_IF +AS_VAR_PUSHDEF([CACHEVAR],[ax_cv_check_[]_AC_LANG_ABBREV[]flags_$4_$1])dnl +AC_CACHE_CHECK([whether _AC_LANG compiler accepts $1], CACHEVAR, [ + ax_check_save_flags=$[]_AC_LANG_PREFIX[]FLAGS + _AC_LANG_PREFIX[]FLAGS="$[]_AC_LANG_PREFIX[]FLAGS $4 $1" + AC_COMPILE_IFELSE([m4_default([$5],[AC_LANG_PROGRAM()])], + [AS_VAR_SET(CACHEVAR,[yes])], + [AS_VAR_SET(CACHEVAR,[no])]) + _AC_LANG_PREFIX[]FLAGS=$ax_check_save_flags]) +AS_VAR_IF(CACHEVAR,yes, + [m4_default([$2], :)], + [m4_default([$3], :)]) +AS_VAR_POPDEF([CACHEVAR])dnl +])dnl AX_CHECK_COMPILE_FLAGS diff --git a/tests/fuzz/Makefile.am b/tests/fuzz/Makefile.am index 70784561..06cb156c 100644 --- a/tests/fuzz/Makefile.am +++ b/tests/fuzz/Makefile.am @@ -1,74 +1,80 @@ -CLEANFILES = LUKS2.pb.h LUKS2.pb.cc +EXTRA_DIST = README.md +dist_noinst_DATA = LUKS2.proto LUKS2_plain_JSON.proto +CLEANFILES = LUKS2.pb.h LUKS2.pb.cc LUKS2_plain_JSON.pb.h LUKS2_plain_JSON.pb.cc -clean-local: - -rm -rf LUKS2.pb.h LUKS2.pb.cc - -TESTS = crypt2_load_fuzz crypt_load_fuzz +distclean-local: + -rm -rf out build LIB_FUZZING_ENGINE := $(if $(LIB_FUZZING_ENGINE),$(LIB_FUZZING_ENGINE),"-fsanitize=fuzzer") +SANITIZER := $(if $(SANITIZER),,"-fsanitize=address") -crypt2_load_fuzz_SOURCES = crypt2_load_fuzz.cc common.c -crypt2_load_fuzz_LDADD = ../../libcryptsetup.la ../../libcrypto_backend.la -crypt2_load_fuzz_LDFLAGS = $(AM_LDFLAGS) $(LIB_FUZZING_ENGINE) -static -crypt2_load_fuzz_CFLAGS = $(AM_CFLAGS) -I$(top_srcdir)/lib -I$(top_srcdir)/tests/fuzz -fsanitize=fuzzer-no-link -crypt2_load_fuzz_CXXFLAGS = $(AM_CXXFLAGS) -I$(top_srcdir)/lib -I$(top_srcdir)/tests/fuzz -fsanitize=fuzzer-no-link +DEPS_PATH := $(top_srcdir)/tests/fuzz/build/static_lib_deps -generate_proto: LUKS2.proto - @protoc LUKS2.proto --cpp_out=. - @protoc LUKS2_plain_JSON.proto --cpp_out=. -LUKS2.pb.h: generate_proto -LUKS2.pb.cc: generate_proto -LUKS2_plain_JSON.pb.cc: generate_proto -LUKS2_plain_JSON.pb.h: generate_proto +crypt2_load_fuzz_SOURCES = crypt2_load_fuzz.cc +crypt2_load_fuzz_LDADD = ../../libcryptsetup.la ../../libcrypto_backend.la -L$(DEPS_PATH)/lib +crypt2_load_fuzz_LDFLAGS = $(AM_LDFLAGS) $(LIB_FUZZING_ENGINE) $(SANITIZER) +crypt2_load_fuzz_CXXFLAGS = $(AM_CXXFLAGS) -I$(top_srcdir)/lib -I$(top_srcdir)/tests/fuzz -BUILT_SOURCES = LUKS2.pb.h LUKS2.pb.cc LUKS2_plain_JSON.pb.h LUKS2_plain_JSON.pb.cc +test-environment-m: + @ if test ! -d $(DEPS_PATH); then \ + echo "You need to build static libraries first; use oss-fuzz-build.sh script."; \ + exit 1; \ + fi +test-environment: | test-environment-m $(DEPS_PATH) -crypt2_load_proto_fuzz_SOURCES = crypt2_load_proto_fuzz.cc common.c LUKS2.pb.cc proto_to_luks2_converter.cc +LUKS2.pb.h: LUKS2.proto + $(DEPS_PATH)/bin/protoc LUKS2.proto --cpp_out=. +LUKS2.pb.cc: LUKS2.pb.h + +LUKS2_plain_JSON.pb.h: LUKS2_plain_JSON.proto + $(DEPS_PATH)/bin/protoc LUKS2_plain_JSON.proto --cpp_out=. +LUKS2_plain_JSON.pb.cc: LUKS2_plain_JSON.pb.h + +generate-proto: | LUKS2.pb.h LUKS2_plain_JSON.pb.h + +nodist_crypt2_load_proto_fuzz_SOURCES = LUKS2.pb.h LUKS2.pb.cc +crypt2_load_proto_fuzz_SOURCES = crypt2_load_proto_fuzz.cc proto_to_luks2_converter.cc crypt2_load_proto_fuzz_LDADD = \ ../../libcryptsetup.la \ ../../libcrypto_backend.la \ - @LIBPROTOBUF_MUTATOR_LIBS@ \ - @PROTOBUF_LIBS@ -crypt2_load_proto_fuzz_LDFLAGS = $(AM_LDFLAGS) $(LIB_FUZZING_ENGINE) -static -crypt2_load_proto_fuzz_CFLAGS = -fsanitize=fuzzer-no-link + -L$(DEPS_PATH)/lib -lprotobuf-mutator-libfuzzer -lprotobuf-mutator -lprotobuf +crypt2_load_proto_fuzz_LDFLAGS = $(AM_LDFLAGS) $(LIB_FUZZING_ENGINE) $(SANITIZER) crypt2_load_proto_fuzz_CXXFLAGS = \ $(AM_CXXFLAGS) \ -I$(top_srcdir)/lib \ -I$(top_srcdir)/tests/fuzz \ - -fsanitize=fuzzer-no-link \ - @LIBPROTOBUF_MUTATOR_CFLAGS@ + -I$(DEPS_PATH)/include \ + -I$(DEPS_PATH)/include/libprotobuf-mutator -I$(DEPS_PATH)/include/libprotobuf-mutator/src -crypt2_load_proto_plain_json_fuzz_SOURCES = crypt2_load_proto_plain_json_fuzz.cc common.c LUKS2_plain_JSON.pb.cc json_proto_converter.cc plain_json_proto_to_luks2_converter.cc +nodist_crypt2_load_proto_plain_json_fuzz_SOURCES = LUKS2_plain_JSON.pb.h LUKS2_plain_JSON.pb.cc +crypt2_load_proto_plain_json_fuzz_SOURCES = crypt2_load_proto_plain_json_fuzz.cc json_proto_converter.cc plain_json_proto_to_luks2_converter.cc crypt2_load_proto_plain_json_fuzz_LDADD = \ ../../libcryptsetup.la \ ../../libcrypto_backend.la \ - @LIBPROTOBUF_MUTATOR_LIBS@ \ - @PROTOBUF_LIBS@ -crypt2_load_proto_plain_json_fuzz_LDFLAGS = $(AM_LDFLAGS) $(LIB_FUZZING_ENGINE) -static -crypt2_load_proto_plain_json_fuzz_CFLAGS = -fsanitize=fuzzer-no-link + -L$(DEPS_PATH)/lib -lprotobuf-mutator-libfuzzer -lprotobuf-mutator -lprotobuf +crypt2_load_proto_plain_json_fuzz_LDFLAGS = $(AM_LDFLAGS) $(LIB_FUZZING_ENGINE) $(SANITIZER) crypt2_load_proto_plain_json_fuzz_CXXFLAGS = \ $(AM_CXXFLAGS) \ -I$(top_srcdir)/lib \ -I$(top_srcdir)/tests/fuzz \ - -fsanitize=fuzzer-no-link \ - @LIBPROTOBUF_MUTATOR_CFLAGS@ + -I$(DEPS_PATH)/include \ + -I$(DEPS_PATH)/include/libprotobuf-mutator -I$(DEPS_PATH)/include/libprotobuf-mutator/src -proto_to_luks2_SOURCES = proto_to_luks2.cc common.c LUKS2.pb.cc proto_to_luks2_converter.cc -proto_to_luks2_LDADD = ../../libcryptsetup.la ../../libcrypto_backend.la @PROTOBUF_LIBS@ -proto_to_luks2_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer-no-link -static -proto_to_luks2_CFLAGS = $(AM_CFLAGS) -I$(top_srcdir)/lib -I$(top_srcdir)/tests/fuzz -proto_to_luks2_CXXFLAGS = $(AM_CXXFLAGS) -I$(top_srcdir)/lib -I$(top_srcdir)/tests/fuzz +nodist_proto_to_luks2_SOURCES = LUKS2.pb.h LUKS2.pb.cc +proto_to_luks2_SOURCES = proto_to_luks2.cc proto_to_luks2_converter.cc +proto_to_luks2_LDADD = ../../libcryptsetup.la ../../libcrypto_backend.la -L$(DEPS_PATH)/lib -lprotobuf +proto_to_luks2_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer-no-link $(SANITIZER) +proto_to_luks2_CXXFLAGS = $(AM_CXXFLAGS) -I$(top_srcdir)/lib -I$(top_srcdir)/tests/fuzz -I$(DEPS_PATH)/include -plain_json_proto_to_luks2_SOURCES = plain_json_proto_to_luks2.cc common.c LUKS2_plain_JSON.pb.cc plain_json_proto_to_luks2_converter.cc json_proto_converter.cc -plain_json_proto_to_luks2_LDADD = ../../libcryptsetup.la ../../libcrypto_backend.la @PROTOBUF_LIBS@ -plain_json_proto_to_luks2_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer-no-link -static -plain_json_proto_to_luks2_CFLAGS = $(AM_CFLAGS) -I$(top_srcdir)/lib -I$(top_srcdir)/tests/fuzz -plain_json_proto_to_luks2_CXXFLAGS = $(AM_CXXFLAGS) -I$(top_srcdir)/lib -I$(top_srcdir)/tests/fuzz +nodist_plain_json_proto_to_luks2_SOURCES = LUKS2_plain_JSON.pb.h LUKS2_plain_JSON.pb.cc +plain_json_proto_to_luks2_SOURCES = plain_json_proto_to_luks2.cc plain_json_proto_to_luks2_converter.cc json_proto_converter.cc +plain_json_proto_to_luks2_LDADD = ../../libcryptsetup.la ../../libcrypto_backend.la -L$(DEPS_PATH)/lib -lprotobuf +plain_json_proto_to_luks2_LDFLAGS = $(AM_LDFLAGS) -fsanitize=fuzzer-no-link $(SANITIZER) +plain_json_proto_to_luks2_CXXFLAGS = $(AM_CXXFLAGS) -I$(top_srcdir)/lib -I$(top_srcdir)/tests/fuzz -I$(DEPS_PATH)/include -check_PROGRAMS = crypt2_load_fuzz crypt2_load_proto_fuzz crypt2_load_proto_plain_json_fuzz proto_to_luks2 plain_json_proto_to_luks2 +if ENABLE_FUZZ_TARGETS +noinst_PROGRAMS = crypt2_load_fuzz crypt2_load_proto_fuzz crypt2_load_proto_plain_json_fuzz proto_to_luks2 plain_json_proto_to_luks2 -clang-only: - @test "$(CC)" == "clang" || (echo "Building fuzz targets is only supported using clang. Please set CC=clang CXX=clang++" && exit 1) - @test "$(CXX)" == "clang++" || (echo "Building fuzz targets is only supported using clang. Please set CC=clang CXX=clang++" && exit 1) - -fuzz-targets: clang-only $(check_PROGRAMS) +fuzz-targets: test-environment generate-proto $(noinst_PROGRAMS) +.PHONY: fuzz-targets +endif diff --git a/tests/fuzz/README.md b/tests/fuzz/README.md new file mode 100644 index 00000000..65c462bb --- /dev/null +++ b/tests/fuzz/README.md @@ -0,0 +1,46 @@ +# Fuzzing target for cryptsetup project + +This directory contains experimental targets for fuzzing testing. +It can be run in the OSS-Fuzz project but also compiled separately. + +# Requirements + +Fuzzers us address sanitizer. To properly detect problems, all +important libraries must be compiled statically with sanitizer enabled. + +Compilation requires *clang* and *clang++* compilers (gcc is not +supported yet). + +# Standalone build + +The script `oss-fuzz-build.sh` can be used to prepare the tree +with pre-compiled library dependencies. +We use upstream git for projects, which can clash with locally +installed versions. The best is to use only basic system installation +without development packages (script will use custom include, libs, +and pkg-config paths). + +# Buid Docker image and fuzzers + +You can also run OSS-Fuzz in a Docker image, use these commands +to prepare fuzzers: +``` +sudo python3 infra/helper.py build_image cryptsetup +sudo python3 infra/helper.py build_fuzzers cryptsetup +``` +On SELinux systems also add: +``` +sudo chcon -Rt svirt_sandbox_file_t build/ +``` +# Run LUKS2 fuzzer +``` +sudo python infra/helper.py run_fuzzer --corpus-dir build/corpus/cryptsetup/crypt2_load_fuzz/ --sanitizer address cryptsetup crypt2_load_fuzz -jobs=8 -workers=8 +``` +# Rebuild fuzz targets for coverage +``` +sudo python infra/helper.py build_fuzzers --sanitizer coverage cryptsetup +``` +# Generate coverage report +``` +sudo python infra/helper.py coverage cryptsetup --no-corpus-download --fuzz-target crypt2_load_fuzz +``` diff --git a/tests/fuzz/common.c b/tests/fuzz/common.c deleted file mode 100644 index 4b56983b..00000000 --- a/tests/fuzz/common.c +++ /dev/null @@ -1,44 +0,0 @@ -/* - * No copyright is claimed. This code is in the public domain; do with - * it what you wish. - * - * Written by Karel Zak - * Petr Uzel - */ - -#include -#include -#include - -/* - * The usleep function was marked obsolete in POSIX.1-2001 and was removed - * in POSIX.1-2008. It was replaced with nanosleep() that provides more - * advantages (like no interaction with signals and other timer functions). - */ -static inline int xusleep(useconds_t usec) -{ - struct timespec waittime = { - .tv_sec = usec / 1000000L, - .tv_nsec = (usec % 1000000L) * 1000 - }; - return nanosleep(&waittime, NULL); -} - -int write_all(int fd, const void *buf, size_t count) -{ - while (count) { - ssize_t tmp; - - errno = 0; - tmp = write(fd, buf, count); - if (tmp > 0) { - count -= tmp; - if (count) - buf = (const void *) ((const char *) buf + tmp); - } else if (errno != EINTR && errno != EAGAIN) - return -1; - if (errno == EAGAIN) /* Try later, *sigh* */ - xusleep(250000); - } - return 0; -} diff --git a/tests/fuzz/common.h b/tests/fuzz/common.h deleted file mode 100644 index e2557dfc..00000000 --- a/tests/fuzz/common.h +++ /dev/null @@ -1 +0,0 @@ -extern int write_all(int fd, const void *buf, size_t count); diff --git a/tests/fuzz/crypt2_load_fuzz.cc b/tests/fuzz/crypt2_load_fuzz.cc index 80616322..f3eea368 100644 --- a/tests/fuzz/crypt2_load_fuzz.cc +++ b/tests/fuzz/crypt2_load_fuzz.cc @@ -38,8 +38,6 @@ extern "C" { #include #include -#include "common.h" - int calculate_checksum(const uint8_t* data, size_t size) { struct crypt_hash *hd = NULL; struct luks2_hdr_disk *hdr = NULL; @@ -127,7 +125,7 @@ int LLVMFuzzerTestOneInput(const uint8_t* data, size_t size) { goto out; } - if (write_all(fd, data, size) != 0) { + if (write_buffer(fd, data, size) != (ssize_t)size) { r = 1; goto out; } diff --git a/tests/fuzz/crypt2_load_proto_fuzz.cc b/tests/fuzz/crypt2_load_proto_fuzz.cc index dadf60e6..e4decde9 100644 --- a/tests/fuzz/crypt2_load_proto_fuzz.cc +++ b/tests/fuzz/crypt2_load_proto_fuzz.cc @@ -33,8 +33,6 @@ extern "C" { #include #include #include - -#include "common.h" } DEFINE_PROTO_FUZZER(const LUKS2_proto::LUKS2_both_headers &headers) { diff --git a/tests/fuzz/crypt2_load_proto_plain_json_fuzz.cc b/tests/fuzz/crypt2_load_proto_plain_json_fuzz.cc index 71f9d9d6..ea957115 100644 --- a/tests/fuzz/crypt2_load_proto_plain_json_fuzz.cc +++ b/tests/fuzz/crypt2_load_proto_plain_json_fuzz.cc @@ -33,8 +33,6 @@ extern "C" { #include #include #include - -#include "common.h" } DEFINE_PROTO_FUZZER(const json_proto::LUKS2_both_headers &headers) { diff --git a/tests/fuzz/oss-fuzz-build.sh b/tests/fuzz/oss-fuzz-build.sh index d84b0fc2..d83bc019 100755 --- a/tests/fuzz/oss-fuzz-build.sh +++ b/tests/fuzz/oss-fuzz-build.sh @@ -1,35 +1,23 @@ #!/usr/bin/env bash +function in_oss_fuzz() +{ + test -n "$FUZZING_ENGINE" +} + echo "Running cryptsetup OSS-Fuzz build script." env set -ex - -apt-get update && apt-get install -y make autoconf automake libtool sharutils \ - dmsetup \ - pkg-config \ - autopoint \ - gettext \ - expect \ - keyutils \ - ninja-build \ - po4a - -# libprotobuf mutator -git clone --depth 1 https://github.com/madler/zlib.git -# no shallow support -git clone http://git.tukaani.org/xz.git -git clone --depth 1 https://github.com/json-c/json-c.git -git clone --depth 1 git://git.kernel.org/pub/scm/fs/ext2/e2fsprogs.git -git clone --depth 1 git://sourceware.org/git/lvm2.git -git clone --depth 1 https://github.com/rpm-software-management/popt.git -git clone --depth 1 https://github.com/protocolbuffers/protobuf.git -git clone --depth 1 https://github.com/google/libprotobuf-mutator.git -git clone --depth 1 git://git.openssl.org/openssl.git - -export PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig/ +PWD=$(pwd) export LC_CTYPE=C.UTF-8 +export SRC=${SRC:-$PWD/build} +export OUT="${OUT:-$PWD/out}" +export DEPS_PATH=$SRC/static_lib_deps + +export PKG_CONFIG_PATH="$DEPS_PATH"/lib/pkgconfig + export CC=${CC:-clang} export CXX=${CXX:-clang++} export LIB_FUZZING_ENGINE="${LIB_FUZZING_ENGINE:--fsanitize=fuzzer}" @@ -37,89 +25,115 @@ export LIB_FUZZING_ENGINE="${LIB_FUZZING_ENGINE:--fsanitize=fuzzer}" SANITIZER="${SANITIZER:-address -fsanitize-address-use-after-scope}" flags="-O1 -fno-omit-frame-pointer -gline-tables-only -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=$SANITIZER -fsanitize=fuzzer-no-link" -export CFLAGS="${CFLAGS:-$flags}" -export CXXFLAGS="${CXXFLAGS:-$flags}" -export OUT="${OUT:-$(pwd)/out}" -export LDFLAGS="$CXXFLAGS" +export CFLAGS="${CFLAGS:-$flags} -I$DEPS_PATH/include" +export CXXFLAGS="${CXXFLAGS:-$flags} -I$DEPS_PATH/include" +export LDFLAGS="$LDFLAGS -L$DEPS_PATH/lib" + +mkdir -p $SRC +mkdir -p $OUT +mkdir -p $DEPS_PATH +cd $SRC + +in_oss_fuzz && apt-get update && apt-get install -y \ + make autoconf automake autopoint libtool pkg-config \ + sharutils gettext expect keyutils ninja-build \ + po4a bison + +[ ! -d zlib ] && git clone --depth 1 https://github.com/madler/zlib.git +[ ! -d xz ] && git clone https://git.tukaani.org/xz.git +[ ! -d json-c ] && git clone --depth 1 https://github.com/json-c/json-c.git +[ ! -d lvm2 ] && git clone --depth 1 https://sourceware.org/git/lvm2.git +[ ! -d popt ] && git clone --depth 1 https://github.com/rpm-software-management/popt.git +#[ ! -d libprotobuf-mutator ] && git clone --depth 1 https://github.com/google/libprotobuf-mutator.git +[ ! -d libprotobuf-mutator ] && git clone --depth 1 -b add-newline https://github.com/bshastry/libprotobuf-mutator.git +[ ! -d openssl ] && git clone --depth 1 https://github.com/openssl/openssl +[ ! -d util-linux ] && git clone --depth 1 https://github.com/util-linux/util-linux +[ ! -d cryptsetup_fuzzing ] && git clone --depth 1 https://gitlab.com/cryptsetup/cryptsetup_fuzzing.git cd openssl -./Configure linux-x86_64 no-shared --static "$CFLAGS" +./Configure -static --prefix="$DEPS_PATH" --libdir=lib make build_generated make -j libcrypto.a make install_dev cd .. -cd e2fsprogs -mkdir build -cd build -../configure --enable-libuuid --enable-libblkid -make -j V=1 -make install-libs-recursive -cd ../.. +cd util-linux +./autogen.sh +./configure --prefix="$DEPS_PATH" --enable-static --disable-shared -disable-all-programs --enable-libuuid --enable-libblkid +make -j +make install +cd .. cd zlib -./configure --static +./configure --prefix="$DEPS_PATH" --static make -j make install cd .. cd xz ./autogen.sh -./configure --enable-static --disable-shared +./configure --prefix="$DEPS_PATH" --enable-static --disable-shared make -j make install cd .. cd json-c -mkdir build +mkdir -p build +rm -fr build/* cd build -cmake .. -DBUILD_SHARED_LIBS=OFF -DBUILD_STATIC_LIBS=ON +cmake .. -DCMAKE_INSTALL_PREFIX="$DEPS_PATH" -DBUILD_SHARED_LIBS=OFF -DBUILD_STATIC_LIBS=ON make -j make install cd ../.. cd lvm2 -./configure --enable-static_link +./configure --prefix="$DEPS_PATH" --enable-static_link --disable-udev_sync --enable-pkgconfig --disable-selinux make -j libdm.device-mapper -mv ./libdm/ioctl/libdevmapper.a /usr/lib/libdevmapper.a -mv ./libdm/libdevmapper.h /usr/include/ +# build of dmsetup.static is broken +# make install_device-mapper +cp ./libdm/ioctl/libdevmapper.a "$DEPS_PATH"/lib/ +cp ./libdm/libdevmapper.h "$DEPS_PATH"/include/ +cp ./libdm/libdevmapper.pc "$PKG_CONFIG_PATH" cd .. cd popt ./autogen.sh -./configure --disable-shared --enable-static +./configure --prefix="$DEPS_PATH" --disable-shared --enable-static make -j make install cd .. -cd protobuf -git submodule update --init --recursive -./autogen.sh -./configure --prefix=/usr --enable-static --disable-shared -make -j -make install - -# rebuild protoc without sanitiser -CFLAGS="" CXXFLAGS="" LDFLAGS="" ./configure --prefix=/usr --enable-static --disable-shared -make -j -mv ./src/protoc /usr/bin/ -cd .. - -mkdir libprotobuf-mutator-build -cd libprotobuf-mutator-build -cmake ../libprotobuf-mutator -DCMAKE_INSTALL_PREFIX=/usr -DPKG_CONFIG_PATH=/usr/lib/pkgconfig -GNinja -DLIB_PROTO_MUTATOR_TESTING=OFF -DCMAKE_BUILD_TYPE=Release +cd libprotobuf-mutator +mkdir -p build +rm -fr build/* +cd build +cmake .. -GNinja \ + -DCMAKE_INSTALL_PREFIX="$DEPS_PATH" \ + -DPKG_CONFIG_PATH="$PKG_CONFIG_PATH" \ + -DLIB_PROTO_MUTATOR_TESTING=OFF \ + -DLIB_PROTO_MUTATOR_DOWNLOAD_PROTOBUF=ON ninja ninja install -cd .. +cd external.protobuf; +cp -Rf bin lib include "$DEPS_PATH"; +cd ../../.. -cd cryptsetup +if in_oss_fuzz; then + mkdir -p cryptsetup/tests/fuzz/build + ln -s ../../../../static_lib_deps cryptsetup/tests/fuzz/build/static_lib_deps + cd cryptsetup +else + cd ../../.. +fi ./autogen.sh -./configure --enable-static --disable-ssh-token --disable-blkid --disable-udev --disable-selinux --disable-pwquality --with-crypto_backend=openssl --disable-shared --enable-fuzz-targets -#./configure --enable-static --disable-ssh-token --disable-blkid --disable-udev --disable-selinux --disable-pwquality --with-crypto_backend=openssl --disable-cryptsetup --disable-veritysetup --disable-integritysetup --enable-shared=0 +./configure --enable-static --disable-asciidoc --disable-ssh-token --disable-udev --disable-selinux --with-crypto_backend=openssl --disable-shared --enable-fuzz-targets make clean make -j fuzz-targets -cp ../*_fuzz_seed_corpus.zip $OUT +cp $SRC/cryptsetup_fuzzing/*_fuzz_seed_corpus.zip $OUT cp tests/fuzz/*_fuzz $OUT cp tests/fuzz/*_fuzz.dict $OUT cp tests/fuzz/proto_to_luks2 $OUT +cp tests/fuzz/plain_json_proto_to_luks2 $OUT + +cd $PWD diff --git a/tests/fuzz/plain_json_proto_to_luks2_converter.cc b/tests/fuzz/plain_json_proto_to_luks2_converter.cc index 01c7cd3c..1aa8f3fd 100644 --- a/tests/fuzz/plain_json_proto_to_luks2_converter.cc +++ b/tests/fuzz/plain_json_proto_to_luks2_converter.cc @@ -31,8 +31,6 @@ extern "C" { #include #include #include - -#include "common.h" } #define OFFSET_OF(strct, field) (((char*)&((struct strct*)0)->field) - (char*)0) @@ -79,8 +77,8 @@ void LUKS2ProtoConverter::emit_luks2_binary_header(const LUKS2_header &header_pr else hdr.hdr_offset = cpu_to_be64(offset); - if (write_all(fd, &hdr, LUKS2_HDR_BIN_LEN) != 0) - err(EXIT_FAILURE, "write_all failed"); + if (write_buffer(fd, &hdr, LUKS2_HDR_BIN_LEN) != LUKS2_HDR_BIN_LEN) + err(EXIT_FAILURE, "write_buffer failed"); if (crypt_hash_write(hd, (char*)&hdr, LUKS2_HDR_BIN_LEN)) err(EXIT_FAILURE, "crypt_hash_write failed"); @@ -88,8 +86,8 @@ void LUKS2ProtoConverter::emit_luks2_binary_header(const LUKS2_header &header_pr uint8_t csum[LUKS2_CHECKSUM_L]; size_t write_size = json_text.length() > hdr_json_area_len - 1 ? hdr_json_area_len - 1 : json_text.length(); - if (write_all(fd, json_text.c_str(), write_size) != 0) - err(EXIT_FAILURE, "write_all failed"); + if (write_buffer(fd, json_text.c_str(), write_size) != (ssize_t)write_size) + err(EXIT_FAILURE, "write_buffer failed"); if (crypt_hash_write(hd, json_text.c_str(), write_size)) err(EXIT_FAILURE, "crypt_hash_write failed"); @@ -108,8 +106,8 @@ void LUKS2ProtoConverter::emit_luks2_binary_header(const LUKS2_header &header_pr if (crypt_hash_final(hd, (char*)csum, (size_t)hash_size)) err(EXIT_FAILURE, "crypt_hash_final failed"); - if (write_all(fd, csum, hash_size) != 0) - err(EXIT_FAILURE, "write_all failed"); + if (write_buffer(fd, csum, hash_size) != hash_size) + err(EXIT_FAILURE, "write_buffer failed"); } } diff --git a/tests/fuzz/proto_to_luks2_converter.cc b/tests/fuzz/proto_to_luks2_converter.cc index 32550ea3..d575ce96 100644 --- a/tests/fuzz/proto_to_luks2_converter.cc +++ b/tests/fuzz/proto_to_luks2_converter.cc @@ -29,8 +29,6 @@ extern "C" { #include #include #include - -#include "common.h" } #define OFFSET_OF(strct, field) (((char*)&((struct strct*)0)->field) - (char*)0) @@ -457,8 +455,8 @@ void LUKS2ProtoConverter::emit_luks2_binary_header(const LUKS2_header &header_pr else hdr.hdr_offset = cpu_to_be64(offset); - if (write_all(fd, &hdr, LUKS2_HDR_BIN_LEN) != 0) - err(EXIT_FAILURE, "write_all failed"); + if (write_buffer(fd, &hdr, LUKS2_HDR_BIN_LEN) != LUKS2_HDR_BIN_LEN) + err(EXIT_FAILURE, "write_buffer failed"); if (crypt_hash_write(hd, (char*)&hdr, LUKS2_HDR_BIN_LEN)) err(EXIT_FAILURE, "crypt_hash_write failed"); @@ -475,8 +473,8 @@ void LUKS2ProtoConverter::emit_luks2_binary_header(const LUKS2_header &header_pr json_text_len = strlen(json_text); size_t write_size = json_text_len > hdr_json_area_len - 1 ? hdr_json_area_len - 1 : json_text_len; - if (write_all(fd, json_text, write_size) != 0) - err(EXIT_FAILURE, "write_all failed"); + if (write_buffer(fd, json_text, write_size) != (ssize_t)write_size) + err(EXIT_FAILURE, "write_buffer failed"); if (crypt_hash_write(hd, json_text, write_size)) err(EXIT_FAILURE, "crypt_hash_write failed"); @@ -496,8 +494,8 @@ void LUKS2ProtoConverter::emit_luks2_binary_header(const LUKS2_header &header_pr if (crypt_hash_final(hd, (char*)csum, (size_t)hash_size)) err(EXIT_FAILURE, "crypt_hash_final failed"); - if (write_all(fd, csum, hash_size) != 0) - err(EXIT_FAILURE, "write_all failed"); + if (write_buffer(fd, csum, hash_size) != hash_size) + err(EXIT_FAILURE, "write_buffer failed"); } }