1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
|
#!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later
set -ex
export LC_CTYPE=C.UTF-8
export CC=${CC:-clang}
export CXX=${CXX:-clang++}
clang_version="$($CC --version | sed -nr 's/.*version ([^ ]+?) .*/\1/p' | sed -r 's/-$//')"
SANITIZER=${SANITIZER:-address -fsanitize-address-use-after-scope}
flags="-O1 -fno-omit-frame-pointer -g -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize=$SANITIZER"
clang_lib="/usr/lib64/clang/${clang_version}/lib/linux"
[ -d "$clang_lib" ] || clang_lib="/usr/lib/clang/${clang_version}/lib/linux"
export CFLAGS=${CFLAGS:-$flags}
export CXXFLAGS=${CXXFLAGS:-$flags}
export LDFLAGS=${LDFLAGS:--L${clang_lib}}
export WORK=${WORK:-$(pwd)}
export OUT=${OUT:-$(pwd)/out}
mkdir -p "$OUT"
build="$WORK/build"
rm -rf "$build"
mkdir -p "$build"
meson_args=("-Db_lundef=false")
if [ -z "$FUZZING_ENGINE" ]; then
meson_args+=("-Dllvm-fuzz=true")
else
# The situation with runtime dependencies on oss-fuzz is complicated as the execution environment differs
# from the build environment
# (https://google.github.io/oss-fuzz/further-reading/fuzzer-environment/#runtime-dependencies). Because
# statically linking isn't viable for us for various reasons, we do a build with most features disabled
# to link against as few libraries as possible. The libraries we do end up linking against happen (by
# chance) to be installed in the oss-fuzz execution environment.
meson_args+=("-Doss-fuzz=true" "--auto-features=disabled" "-Dlibmount=enabled" "-Dnspawn=enabled" "-Dresolve=true")
apt-get update
apt-get install -y gperf m4 gettext python3-pip \
libmount-dev \
pkg-config wget python3-jinja2 zipmerge zstd
if [[ "$ARCHITECTURE" == i386 ]]; then
apt-get install -y pkg-config:i386 libcrypt-dev:i386 libmount-dev:i386
export PKG_CONFIG=i686-linux-gnu-pkg-config
fi
pip3 install -r .github/workflows/requirements.txt --require-hashes
# https://github.com/google/oss-fuzz/issues/6868
ORIG_PYTHONPATH=$(python3 -c 'import sys;print(":".join(sys.path[1:]))')
export PYTHONPATH="$ORIG_PYTHONPATH:/usr/lib/python3/dist-packages/"
if [[ "$SANITIZER" == undefined ]]; then
additional_ubsan_checks=pointer-overflow,alignment
UBSAN_FLAGS="-fsanitize=$additional_ubsan_checks -fno-sanitize-recover=$additional_ubsan_checks"
CFLAGS="$CFLAGS $UBSAN_FLAGS"
CXXFLAGS="$CXXFLAGS $UBSAN_FLAGS"
fi
if [[ "$SANITIZER" == introspector ]]; then
# fuzz-introspector passes -fuse-ld=gold and -flto using CFLAGS/LDFLAGS and due to
# https://github.com/mesonbuild/meson/issues/6377#issuecomment-575977919 and
# https://github.com/mesonbuild/meson/issues/6377 it doesn't mix well with meson.
# It's possible to build systemd with duct tape there using something like
# https://github.com/google/oss-fuzz/pull/7583#issuecomment-1104011067 but
# apparently even with gold and lto some parts of systemd are missing from
# reports (presumably due to https://github.com/google/oss-fuzz/issues/7598).
# Let's just fail here for now to make it clear that fuzz-introspector isn't supported.
exit 1
fi
fi
if ! meson setup "$build" "${meson_args[@]}"; then
cat "$build/meson-logs/meson-log.txt"
exit 1
fi
ninja -v -C "$build" fuzzers
# Compressed BCD files are kept in test/test-bcd so let's unpack them
# and put them all in the seed corpus.
bcd=$(mktemp -d)
for i in test/test-bcd/*.zst; do
unzstd "$i" -o "$bcd/$(basename "${i%.zst}")";
done
zip -jqr "$OUT/fuzz-bcd_seed_corpus.zip" "$bcd"
rm -rf "$bcd"
hosts=$(mktemp)
wget -O "$hosts" https://raw.githubusercontent.com/StevenBlack/hosts/master/hosts
zip -jq "$OUT/fuzz-etc-hosts_seed_corpus.zip" "$hosts"
rm -rf "$hosts"
# The seed corpus is a separate flat archive for each fuzzer,
# with a fixed name ${fuzzer}_seed_corpus.zip.
for d in test/fuzz/fuzz-*; do
fuzzer="$(basename "$d")"
# Include the build-generated corpora if any as well
readarray -t generated < <(find "$build/test/fuzz" -maxdepth 1 -name "${fuzzer}*" -type f)
zip -jqr "$OUT/${fuzzer}_seed_corpus.zip" "$d" "${generated[@]}"
done
# get fuzz-dns-packet corpus
df="$build/dns-fuzzing"
git clone --depth 1 https://github.com/CZ-NIC/dns-fuzzing "$df"
zip -jqr "$OUT/fuzz-dns-packet_seed_corpus.zip" "$df/packet"
install -Dt "$OUT/src/shared/" \
"$build"/src/shared/libsystemd-shared-*.so \
"$build"/src/core/libsystemd-core-*.so
# Most i386 libraries have to be brought to the runtime environment somehow. Ideally they
# should be linked statically but since it isn't possible another way to keep them close
# to the fuzz targets is used here. The dependencies are copied to "$OUT/src/shared" and
# then 'rpath' is tweaked to make it possible for the linker to find them there. "$OUT/src/shared"
# is chosen because the runtime search path of all the fuzz targets already points to it
# to load "libsystemd-shared" and "libsystemd-core". Stuff like that should be avoided on
# x86_64 because it tends to break coverage reports, fuzz-introspector, CIFuzz and so on.
if [[ "$ARCHITECTURE" == i386 ]]; then
for lib_path in $(ldd "$OUT"/src/shared/libsystemd-shared-*.so | awk '/=> \/lib/ { print $3 }'); do
lib_name=$(basename "$lib_path")
cp "$lib_path" "$OUT/src/shared"
patchelf --set-rpath \$ORIGIN "$OUT/src/shared/$lib_name"
done
patchelf --set-rpath \$ORIGIN "$OUT"/src/shared/libsystemd-shared-*.so
fi
wget -O "$OUT/fuzz-json.dict" https://raw.githubusercontent.com/rc0r/afl-fuzz/master/dictionaries/json.dict
find "$build" -maxdepth 1 -type f -executable -name "fuzz-*" -exec mv {} "$OUT" \;
find src -type f -name "fuzz-*.dict" -exec cp {} "$OUT" \;
cp src/fuzz/*.options "$OUT"
if [[ "$MERGE_WITH_OSS_FUZZ_CORPORA" == "yes" ]]; then
for f in "$OUT/"fuzz-*; do
[[ -x "$f" ]] || continue
fuzzer=$(basename "$f")
t=$(mktemp)
if wget -O "$t" "https://storage.googleapis.com/systemd-backup.clusterfuzz-external.appspot.com/corpus/libFuzzer/systemd_${fuzzer}/public.zip"; then
zipmerge "$OUT/${fuzzer}_seed_corpus.zip" "$t"
fi
rm -rf "$t"
done
fi
|