diff --git a/fuzz/bpf-object-fuzzer.c b/fuzz/bpf-object-fuzzer.c new file mode 100644 index 0000000..89286e2 --- /dev/null +++ b/fuzz/bpf-object-fuzzer.c @@ -0,0 +1,23 @@ +#include "libbpf.h" + +static int libbpf_print_fn(enum libbpf_print_level level, const char *format, va_list args) +{ + return 0; +} + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + struct bpf_object *obj = NULL; + DECLARE_LIBBPF_OPTS(bpf_object_open_opts, opts); + int err; + + libbpf_set_print(libbpf_print_fn); + + opts.object_name = "fuzz-object"; + obj = bpf_object__open_mem(data, size, &opts); + err = libbpf_get_error(obj); + if (err) + return 0; + + bpf_object__close(obj); + return 0; +} diff --git a/fuzz/bpf-object-fuzzer_seed_corpus.zip b/fuzz/bpf-object-fuzzer_seed_corpus.zip new file mode 100644 index 0000000..602b381 Binary files /dev/null and b/fuzz/bpf-object-fuzzer_seed_corpus.zip differ diff --git a/scripts/build-fuzzers.sh b/scripts/build-fuzzers.sh new file mode 100755 index 0000000..0591451 --- /dev/null +++ b/scripts/build-fuzzers.sh @@ -0,0 +1,60 @@ +#!/bin/bash +set -eux + +SANITIZER=${SANITIZER:-address} +flags="-O1 -fno-omit-frame-pointer -g -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=$SANITIZER -fsanitize=fuzzer-no-link" + +export CC=${CC:-clang} +export CFLAGS=${CFLAGS:-$flags} + +export CXX=${CXX:-clang++} +export CXXFLAGS=${CXXFLAGS:-$flags} + +cd "$(dirname -- "$0")/.." + +export OUT=${OUT:-"$(pwd)/out"} +mkdir -p "$OUT" + +export LIB_FUZZING_ENGINE=${LIB_FUZZING_ENGINE:--fsanitize=fuzzer} + +# Ideally libbelf should be built using release tarballs available +# at https://sourceware.org/elfutils/ftp/. Unfortunately sometimes they +# fail to compile (for example, elfutils-0.185 fails to compile with LDFLAGS enabled +# due to https://bugs.gentoo.org/794601) so let's just point the script to +# commits referring to versions of libelf that actually can be built +elfutils=$(mktemp -d) +git clone git://sourceware.org/git/elfutils.git "$elfutils" +( +cd "$elfutils" +git checkout 983e86fd89e8bf02f2d27ba5dce5bf078af4ceda +git log --oneline -1 + +# ASan isn't compatible with -Wl,--no-undefined: https://github.com/google/sanitizers/issues/380 +find -name Makefile.am | xargs sed -i 's/,--no-undefined//' + +# ASan isn't compatible with -Wl,-z,defs either: +# https://clang.llvm.org/docs/AddressSanitizer.html#usage +sed -i 's/^\(ZDEFS_LDFLAGS=\).*/\1/' configure.ac + + +autoreconf -i -f +if ! ./configure --enable-maintainer-mode --disable-debuginfod --disable-libdebuginfod \ + CC="$CC" CFLAGS="-Wno-error $CFLAGS" CXX="$CXX" CXXFLAGS="-Wno-error $CXXFLAGS" LDFLAGS="$CFLAGS"; then + cat config.log + exit 1 +fi + +make -C config -j$(nproc) V=1 +make -C lib -j$(nproc) V=1 +make -C libelf -j$(nproc) V=1 +) + +make -C src BUILD_STATIC_ONLY=y V=1 clean +make -C src -j$(nproc) CFLAGS="-I$elfutils/libelf $CFLAGS" BUILD_STATIC_ONLY=y V=1 + +$CC $CFLAGS -Isrc -Iinclude -Iinclude/uapi -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -c fuzz/bpf-object-fuzzer.c -o bpf-object-fuzzer.o +$CXX $CXXFLAGS $LIB_FUZZING_ENGINE bpf-object-fuzzer.o src/libbpf.a "$elfutils/libelf/libelf.a" -l:libz.a -o "$OUT/bpf-object-fuzzer" + +cp fuzz/bpf-object-fuzzer_seed_corpus.zip "$OUT" + +rm -rf "$elfutils"