2020-03-04 12:35:06 +03:00
#!/usr/bin/env bash
2020-11-09 07:23:58 +03:00
# SPDX-License-Identifier: LGPL-2.1-or-later
2018-01-14 03:51:07 +03:00
set -ex
export LC_CTYPE = C.UTF-8
2018-03-12 17:59:10 +03:00
export CC = ${ CC :- clang }
export CXX = ${ CXX :- clang ++ }
clang_version = " $( $CC --version | sed -nr 's/.*version ([^ ]+?) .*/\1/p' | sed -r 's/-$//' ) "
2018-01-16 18:25:43 +03:00
SANITIZER = ${ SANITIZER :- address -fsanitize-address-use-after-scope }
2022-01-05 01:47:46 +03:00
flags = " -O1 -fno-omit-frame-pointer -g -DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION -fsanitize= $SANITIZER "
2018-01-16 18:25:43 +03:00
2018-03-12 17:59:10 +03:00
clang_lib = " /usr/lib64/clang/ ${ clang_version } /lib/linux "
[ -d " $clang_lib " ] || clang_lib = " /usr/lib/clang/ ${ clang_version } /lib/linux "
2018-01-16 18:25:43 +03:00
export CFLAGS = ${ CFLAGS :- $flags }
export CXXFLAGS = ${ CXXFLAGS :- $flags }
2018-03-12 17:59:10 +03:00
export LDFLAGS = ${ LDFLAGS :- -L ${ clang_lib } }
2018-01-16 18:25:43 +03:00
export WORK = ${ WORK :- $( pwd ) }
export OUT = ${ OUT :- $( pwd ) /out }
2021-09-29 22:28:55 +03:00
mkdir -p " $OUT "
2018-01-16 18:25:43 +03:00
2021-09-29 22:28:55 +03:00
build = " $WORK /build "
rm -rf " $build "
mkdir -p " $build "
2018-01-16 16:36:56 +03:00
2023-08-10 19:11:25 +03:00
meson_args = ( "-Db_lundef=false" )
2018-01-16 18:25:43 +03:00
if [ -z " $FUZZING_ENGINE " ] ; then
2023-08-10 19:11:25 +03:00
meson_args += ( "-Dllvm-fuzz=true" )
2020-05-21 09:20:01 +03:00
else
2023-08-10 19:11:25 +03:00
meson_args += ( "-Doss-fuzz=true" "--auto-features=disabled" )
2021-11-17 11:47:29 +03:00
apt-get update
apt-get install -y gperf m4 gettext python3-pip \
2022-05-29 09:52:54 +03:00
libcap-dev libmount-dev \
2023-02-26 16:09:44 +03:00
pkg-config wget python3-jinja2 zipmerge zstd
2021-12-27 02:26:56 +03:00
2022-05-29 09:52:54 +03:00
if [ [ " $ARCHITECTURE " = = i386 ] ] ; then
apt-get install -y pkg-config:i386 libcap-dev:i386 libmount-dev:i386
fi
2021-11-19 19:23:03 +03:00
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/ "
2021-11-17 11:47:29 +03:00
2020-05-21 09:20:01 +03:00
if [ [ " $SANITIZER " = = undefined ] ] ; then
2021-12-28 20:10:18 +03:00
additional_ubsan_checks = pointer-overflow,alignment
UBSAN_FLAGS = " -fsanitize= $additional_ubsan_checks -fno-sanitize-recover= $additional_ubsan_checks "
2020-05-21 09:20:01 +03:00
CFLAGS = " $CFLAGS $UBSAN_FLAGS "
CXXFLAGS = " $CXXFLAGS $UBSAN_FLAGS "
fi
2022-04-21 21:00:43 +03:00
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
2018-01-16 18:25:43 +03:00
fi
2023-08-10 19:11:25 +03:00
if ! meson setup " $build " " ${ meson_args [@] } " ; then
2021-09-29 22:28:55 +03:00
cat " $build /meson-logs/meson-log.txt "
2021-02-01 15:40:57 +03:00
exit 1
fi
2021-09-29 22:28:55 +03:00
ninja -v -C " $build " fuzzers
2018-01-14 03:51:07 +03:00
2021-12-27 02:26:56 +03:00
# 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 "
2022-01-20 08:06:49 +03:00
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 "
2018-07-07 18:43:40 +03:00
# The seed corpus is a separate flat archive for each fuzzer,
# with a fixed name ${fuzzer}_seed_corpus.zip.
2022-01-29 18:22:43 +03:00
for d in test/fuzz/fuzz-*; do
2023-01-07 12:27:05 +03:00
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 [@] } "
2018-01-20 03:44:56 +03:00
done
# get fuzz-dns-packet corpus
2021-09-29 22:28:55 +03:00
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 "
2018-01-14 03:51:07 +03:00
meson: create new libsystemd-core.so private shared library
The scheme is very similar to libsystemd-shared.so: instead of building a
static library, we build a shared library from the same objects and link the
two users to it. Both systemd and systemd-analyze consist mostly of the fairly
big code in libcore, so we save a bit on the installation:
(-0g, no strip)
-rwxr-xr-x 5238864 Dec 14 12:52 /var/tmp/inst1/usr/lib/systemd/systemd
-rwxr-xr-x 5399600 Dec 14 12:52 /var/tmp/inst1/usr/bin/systemd-analyze
-rwxr-xr-x 244912 Dec 14 13:17 /var/tmp/inst2/usr/lib/systemd/systemd
-rwxr-xr-x 461224 Dec 14 13:17 /var/tmp/inst2/usr/bin/systemd-analyze
-rwxr-xr-x 5271568 Dec 14 13:17 /var/tmp/inst2/usr/lib/systemd/libsystemd-core-250.so
(-0g, strip)
-rwxr-xr-x 2522080 Dec 14 13:19 /var/tmp/inst1/usr/lib/systemd/systemd
-rwxr-xr-x 2604160 Dec 14 13:19 /var/tmp/inst1/usr/bin/systemd-analyze
-rwxr-xr-x 113304 Dec 14 13:19 /var/tmp/inst2/usr/lib/systemd/systemd
-rwxr-xr-x 207656 Dec 14 13:19 /var/tmp/inst2/usr/bin/systemd-analyze
-rwxr-xr-x 2648520 Dec 14 13:19 /var/tmp/inst2/usr/lib/systemd/libsystemd-core-250.so
So for systemd itself we grow a bit (2522080 → 2648520+113304=2761824), but
overall we save. The most is saved on all the test files that link to libcore,
if they are installed, because there's 15 of them:
$ du -s /var/tmp/inst?
220096 /var/tmp/inst1
122960 /var/tmp/inst2
I also considered making systemd-analyze a symlink to /usr/lib/systemd/systemd
and turning systemd into a multicall binary. We did something like this with
udevd and udevadm. But that solution doesn't fit well in this case.
systemd-analyze has a bunch of functionality that is not used in systemd,
so the systemd binary would need to grow quite a bit. And we're likely to
add new types of verification or introspection features in analyze, and this
baggage would only grow. In addition, there are the test binaries which also
benefit from this.
2021-12-14 15:20:28 +03:00
install -Dt " $OUT /src/shared/ " \
" $build " /src/shared/libsystemd-shared-*.so \
" $build " /src/core/libsystemd-core-*.so
2018-01-14 03:51:07 +03:00
2022-05-29 09:52:54 +03:00
# 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
2023-05-08 13:48:37 +03:00
# then 'rpath' is tweaked to make it possible for the linker to find them there. "$OUT/src/shared"
2022-05-29 09:52:54 +03:00
# 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
2023-05-08 13:48:37 +03:00
for lib_path in $( ldd " $OUT " /src/shared/libsystemd-shared-*.so | awk '/=> \/lib/ { print $3 }' ) ; do
2022-05-29 09:52:54 +03:00
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
2021-09-29 22:28:55 +03:00
wget -O " $OUT /fuzz-json.dict " https://raw.githubusercontent.com/rc0r/afl-fuzz/master/dictionaries/json.dict
2018-08-01 13:25:26 +03:00
2021-09-29 22:28:55 +03:00
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 "
2022-01-30 00:36:41 +03:00
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