From 393a058d061d49d5c3055fa9eefafb4c0c31ccc3 Mon Sep 17 00:00:00 2001 From: Evgeny Vereshchagin Date: Sat, 22 Jan 2022 01:05:11 +0000 Subject: [PATCH] tests: move the fuzzer upstream It should make it easier to start using CFLite or something like that to fuzz libbpf without getting pointless CVEs :-) More importantly, now it's possible to build the fuzzer by just cloning the repository, installing clang and running `./scripts/build-fuzzers.h`: ``` git clone https://github.com/libbpf/libbpf ./scripts/build-fuzzers.h unzip -d CORPUS fuzz/bpf-object-fuzzer_seed_corpus.zip ./out/bpf-object-fuzzer CORPUS ``` It should make it easier (for me at least) to report some elfutils bugs because they are much easier to reproduce manually now. --- fuzz/bpf-object-fuzzer.c | 23 ++++++++++ fuzz/bpf-object-fuzzer_seed_corpus.zip | Bin 0 -> 1091 bytes scripts/build-fuzzers.sh | 60 +++++++++++++++++++++++++ 3 files changed, 83 insertions(+) create mode 100644 fuzz/bpf-object-fuzzer.c create mode 100644 fuzz/bpf-object-fuzzer_seed_corpus.zip create mode 100755 scripts/build-fuzzers.sh 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 0000000000000000000000000000000000000000..602b3812c46ce03b56f89b3f8f94f06954ef0015 GIT binary patch literal 1091 zcmWIWW@Zs#U|`^2C}TGZ@pR&yIGLG&!GVi`ftNvsAvZHGGdD3uFR36+FF!PdlYyBb z{B(HUypnZvBhbdi;_vz1YWO(mhZm)A_G(GPvU-id*X-IV;A(f=jw8$_3p`yY2Q)z zwvW-?$!5+%nf;vIdsLWTu8=<>vtY&!^OYA0D<;U4X)~6y{I=YbxX;$`ciAT8{|;y7 zsal^C)%s@@;VUoYwmEC|nf&Ja*Y@(RPr9+KT{g|E_HwFu>}hky{4FxU`xCFkE`IrX zTd3al?Do@Zr@jBV?&7txrH3qXg zR&G|I_UG4OrCCw7rCzp1^>eJRU(qbNR~}Sqb|F!!$Rm5V&6!(Q{{3UGU%Ini?6Z%2 zyLCXOgq}fJTIJ6(s@pb|>^u;rKb5P;vG8Ti!$V$-haOzKWO{7rvmXnl+VY!h4>he} z&RLygW^247NGtcQUeN5vYxM>6XLD8o^Gw~<5*CkJQ^FT2xeaE|wqk_eEIsOF8?tW2vjXQDfnWF~3YWklZ`KUAZ z3`6hgjgJmTo+~>Wy{Ax6&-2HumfJ%2rhIVb?EV|f@qX?N-dXwUKL36`YumK=*ee2G zcFqetn6<6;aH8ARS5;xQ5B{xgIav5>CwNpb+f=<=Et9=nMJA2S!~m!f3IJ?_Q(97yPw_X`|$tUX7@+Ow)Ro%iHYma z#J@fq?_d7=X@~ab{z6}|{|^jvj{W@Jsej-5=O44`9}8?0{=L@yQO_9Q&B!Fjj4N+T m0P{QqENKMMXgQq~lGD+0d4M-78%QxD5C#M3TfpqkzyJUk4eOl% literal 0 HcmV?d00001 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"