You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
186 lines
6.0 KiB
186 lines
6.0 KiB
From 25338c37915521876c84bca196de50d73c3c17ea Mon Sep 17 00:00:00 2001 |
|
From: Frantisek Sumsal <frantisek@sumsal.cz> |
|
Date: Mon, 13 Dec 2021 20:50:28 +0100 |
|
Subject: [PATCH] test: fuzz our dbus interfaces with dfuzzer |
|
|
|
(cherry picked from commit 354b3364aa63620a0f732bb8a6fe9332a4f550e4) |
|
|
|
Related: #2087652 |
|
--- |
|
test/TEST-21-DFUZZER/Makefile | 1 + |
|
test/TEST-21-DFUZZER/test.sh | 24 +++++++++ |
|
test/test-functions | 1 + |
|
test/units/testsuite-21.service | 10 ++++ |
|
test/units/testsuite-21.sh | 94 +++++++++++++++++++++++++++++++++ |
|
5 files changed, 130 insertions(+) |
|
create mode 120000 test/TEST-21-DFUZZER/Makefile |
|
create mode 100755 test/TEST-21-DFUZZER/test.sh |
|
create mode 100644 test/units/testsuite-21.service |
|
create mode 100755 test/units/testsuite-21.sh |
|
|
|
diff --git a/test/TEST-21-DFUZZER/Makefile b/test/TEST-21-DFUZZER/Makefile |
|
new file mode 120000 |
|
index 0000000000..e9f93b1104 |
|
--- /dev/null |
|
+++ b/test/TEST-21-DFUZZER/Makefile |
|
@@ -0,0 +1 @@ |
|
+../TEST-01-BASIC/Makefile |
|
\ No newline at end of file |
|
diff --git a/test/TEST-21-DFUZZER/test.sh b/test/TEST-21-DFUZZER/test.sh |
|
new file mode 100755 |
|
index 0000000000..ecc04e368c |
|
--- /dev/null |
|
+++ b/test/TEST-21-DFUZZER/test.sh |
|
@@ -0,0 +1,24 @@ |
|
+#!/usr/bin/env bash |
|
+# SPDX-License-Identifier: LGPL-2.1-or-later |
|
+set -e |
|
+ |
|
+TEST_DESCRIPTION="Fuzz our D-Bus interfaces with dfuzzer" |
|
+TEST_NO_NSPAWN=1 |
|
+TEST_SUPPORTING_SERVICES_SHOULD_BE_MASKED=0 |
|
+QEMU_TIMEOUT="${QEMU_TIMEOUT:-1800}" |
|
+ |
|
+# shellcheck source=test/test-functions |
|
+. "${TEST_BASE_DIR:?}/test-functions" |
|
+ |
|
+command -v dfuzzer >/dev/null || exit 0 |
|
+ |
|
+test_append_files() { |
|
+ local workspace="${1:?}" |
|
+ |
|
+ image_install dfuzzer /etc/dfuzzer.conf |
|
+ |
|
+ # Enable all systemd-related services, including the D-Bus ones |
|
+ "$SYSTEMCTL" --root="${workspace:?}" preset-all |
|
+} |
|
+ |
|
+do_test "$@" |
|
diff --git a/test/test-functions b/test/test-functions |
|
index 44f465c914..079a7249e4 100644 |
|
--- a/test/test-functions |
|
+++ b/test/test-functions |
|
@@ -99,6 +99,7 @@ SYSTEMD_JOURNAL_REMOTE="${SYSTEMD_JOURNAL_REMOTE:-$(command -v "$BUILD_DIR/syste |
|
SYSTEMD="${SYSTEMD:-$(command -v "$BUILD_DIR/systemd" || command -v "$ROOTLIBDIR/systemd")}" |
|
SYSTEMD_NSPAWN="${SYSTEMD_NSPAWN:-$(command -v "$BUILD_DIR/systemd-nspawn" || command -v systemd-nspawn)}" |
|
JOURNALCTL="${JOURNALCTL:-$(command -v "$BUILD_DIR/journalctl" || command -v journalctl)}" |
|
+SYSTEMCTL="${SYSTEMCTL:-$(command -v "$BUILD_DIR/systemctl" || command -v systemctl)}" |
|
|
|
TESTFILE="${BASH_SOURCE[1]}" |
|
if [ -z "$TESTFILE" ]; then |
|
diff --git a/test/units/testsuite-21.service b/test/units/testsuite-21.service |
|
new file mode 100644 |
|
index 0000000000..a5f77d07b4 |
|
--- /dev/null |
|
+++ b/test/units/testsuite-21.service |
|
@@ -0,0 +1,10 @@ |
|
+# SPDX-License-Identifier: LGPL-2.1-or-later |
|
+[Unit] |
|
+Description=Fuzz our D-Bus interfaces with dfuzzer |
|
+After=dbus.service multi-user.target |
|
+Wants=dbus.service multi-user.target |
|
+ |
|
+[Service] |
|
+ExecStartPre=rm -f /failed /skipped /testok |
|
+ExecStart=/usr/lib/systemd/tests/testdata/units/%N.sh |
|
+Type=oneshot |
|
diff --git a/test/units/testsuite-21.sh b/test/units/testsuite-21.sh |
|
new file mode 100755 |
|
index 0000000000..43b5fb6f22 |
|
--- /dev/null |
|
+++ b/test/units/testsuite-21.sh |
|
@@ -0,0 +1,94 @@ |
|
+#!/usr/bin/env bash |
|
+# SPDX-License-Identifier: LGPL-2.1-or-later |
|
+set -eux |
|
+set -o pipefail |
|
+ |
|
+# Save the end.service state before we start fuzzing, as it might get changed |
|
+# on the fly by one of the fuzzers |
|
+systemctl list-jobs | grep -F 'end.service' && SHUTDOWN_AT_EXIT=1 || SHUTDOWN_AT_EXIT=0 |
|
+ |
|
+at_exit() { |
|
+ # "Safety net" - check for any coredumps which might have not caused dfuzzer |
|
+ # to stop & return an error (we need to do this now before truncating the |
|
+ # journal) |
|
+ # TODO: check fo ASan/UBSan errors |
|
+ local found_cd=0 |
|
+ while read -r exe; do |
|
+ coredumctl info "$exe" |
|
+ found_cd=1 |
|
+ done < <(coredumpctl -F COREDUMP_EXE | sort -u) |
|
+ [[ $found_cd -eq 0 ]] || exit 1 |
|
+ |
|
+ # We have to call the end.service explicitly even if it's specified on |
|
+ # the kernel cmdline via systemd.wants=end.service, since dfuzzer calls |
|
+ # org.freedesktop.systemd1.Manager.ClearJobs() which drops the service |
|
+ # from the queue |
|
+ [[ $SHUTDOWN_AT_EXIT -ne 0 ]] && systemctl start --job-mode=flush end.service |
|
+} |
|
+ |
|
+trap at_exit EXIT |
|
+ |
|
+systemctl log-level info |
|
+ |
|
+# TODO |
|
+# * check for possibly newly introduced buses? |
|
+BUS_LIST=( |
|
+ org.freedesktop.home1 |
|
+ org.freedesktop.hostname1 |
|
+ org.freedesktop.import1 |
|
+ org.freedesktop.locale1 |
|
+ org.freedesktop.login1 |
|
+ org.freedesktop.machine1 |
|
+ org.freedesktop.network1 |
|
+ org.freedesktop.portable1 |
|
+ org.freedesktop.resolve1 |
|
+ org.freedesktop.systemd1 |
|
+ org.freedesktop.timedate1 |
|
+ org.freedesktop.timesync1 |
|
+) |
|
+ |
|
+# systemd-oomd requires PSI |
|
+if tail -n +1 /proc/pressure/{cpu,io,memory}; then |
|
+ BUS_LIST+=(org.freedesktop.oom1) |
|
+fi |
|
+ |
|
+SESSION_BUS_LIST=( |
|
+ org.freedesktop.systemd1 |
|
+) |
|
+ |
|
+# Maximum payload size generated by dfuzzer (in bytes) - default: 50K |
|
+PAYLOAD_MAX=50000 |
|
+# Tweak the maximum payload size if we're running under sanitizers, since |
|
+# with larger payloads we start hitting reply timeouts |
|
+if [[ -v ASAN_OPTIONS || -v UBSAN_OPTIONS ]]; then |
|
+ PAYLOAD_MAX=10000 # 10K |
|
+fi |
|
+ |
|
+# Overmount /var/lib/machines with a size-limited tmpfs, as fuzzing |
|
+# the org.freedesktop.machine1 stuff makes quite a mess |
|
+mount -t tmpfs -o size=50M tmpfs /var/lib/machines |
|
+ |
|
+# Fuzz both the system and the session buses (where applicable) |
|
+for bus in "${BUS_LIST[@]}"; do |
|
+ echo "Bus: $bus (system)" |
|
+ systemd-run --pipe --wait \ |
|
+ -- dfuzzer -v -b "$PAYLOAD_MAX" -n "$bus" |
|
+ |
|
+ # Let's reload the systemd daemon to test (de)serialization as well |
|
+ systemctl daemon-reload |
|
+done |
|
+ |
|
+umount /var/lib/machines |
|
+ |
|
+for bus in "${SESSION_BUS_LIST[@]}"; do |
|
+ echo "Bus: $bus (session)" |
|
+ systemd-run --machine 'testuser@.host' --user --pipe --wait \ |
|
+ -- dfuzzer -v -b "$PAYLOAD_MAX" -n "$bus" |
|
+ |
|
+ # Let's reload the systemd user daemon to test (de)serialization as well |
|
+ systemctl --machine 'testuser@.host' --user daemon-reload |
|
+done |
|
+ |
|
+echo OK >/testok |
|
+ |
|
+exit 0
|
|
|