From 9b112737fa61e166521d0f21489f9cefdf3dc966 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Mon, 27 May 2024 19:22:11 +0200 Subject: [PATCH 01/13] mkosi: Install bpftrace --- mkosi.images/system/mkosi.conf | 1 + 1 file changed, 1 insertion(+) diff --git a/mkosi.images/system/mkosi.conf b/mkosi.images/system/mkosi.conf index 6ab91b19a9..f543b6410f 100644 --- a/mkosi.images/system/mkosi.conf +++ b/mkosi.images/system/mkosi.conf @@ -31,6 +31,7 @@ Packages= acl attr bash-completion + bpftrace coreutils curl diffutils From fe2a793b2daeca96d8cf2d5be416ed78e7055ec8 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Tue, 28 May 2024 10:14:07 +0200 Subject: [PATCH 02/13] mkosi: Stop installing dbus-broker on OpenSUSE dbus-broker and dbus-daemon have not been made interchangable on OpenSUSE so we currently end up with dbus-broker used for the system bus and dbus-daemon for the session bus. Let's stick to dbus-daemon on OpenSUSE until they switch to dbus-broker. --- mkosi.images/system/mkosi.conf.d/10-opensuse/mkosi.conf | 1 - 1 file changed, 1 deletion(-) diff --git a/mkosi.images/system/mkosi.conf.d/10-opensuse/mkosi.conf b/mkosi.images/system/mkosi.conf.d/10-opensuse/mkosi.conf index 922b8338c8..b3172bfc14 100644 --- a/mkosi.images/system/mkosi.conf.d/10-opensuse/mkosi.conf +++ b/mkosi.images/system/mkosi.conf.d/10-opensuse/mkosi.conf @@ -29,7 +29,6 @@ Packages= bpftool btrfs-progs cryptsetup - dbus-broker device-mapper dhcp-server docbook-xsl-stylesheets From 412e2a6487adad3329a65ebae642528a3d914f09 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Sun, 26 May 2024 16:28:21 +0200 Subject: [PATCH 03/13] TEST-05-RLIMITS: Bump memory limits When running with sanitizers we need more memory otherwise the unit gets OOM killed. --- test/units/TEST-05-RLIMITS.effective-limit.sh | 32 +++++++++---------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/test/units/TEST-05-RLIMITS.effective-limit.sh b/test/units/TEST-05-RLIMITS.effective-limit.sh index 3ff8e83140..f6639f1840 100755 --- a/test/units/TEST-05-RLIMITS.effective-limit.sh +++ b/test/units/TEST-05-RLIMITS.effective-limit.sh @@ -9,22 +9,22 @@ set -o pipefail pre=test05 cat >/run/systemd/system/"$pre"alpha.slice </run/systemd/system/"$pre"alpha-beta.slice </run/systemd/system/"$pre"alpha-beta-gamma.slice < Date: Sun, 26 May 2024 18:22:54 +0200 Subject: [PATCH 04/13] TEST-02-UNITTESTS: Fix exit code checks --- test/units/TEST-02-UNITTESTS.sh | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/test/units/TEST-02-UNITTESTS.sh b/test/units/TEST-02-UNITTESTS.sh index 0c8de536ef..aac55ea17c 100755 --- a/test/units/TEST-02-UNITTESTS.sh +++ b/test/units/TEST-02-UNITTESTS.sh @@ -60,15 +60,7 @@ run_test() { exec {LOCK_FD}> /lock flock --exclusive ${LOCK_FD} - if [[ $ret -ne 0 && $ret != 77 && $ret != 127 ]]; then - echo "$name failed with $ret" - echo "$name" >>/failed-tests - { - echo "--- $name begin ---" - journalctl --unit="$name" --no-hostname -o short-monotonic - echo "--- $name end ---" - } >>/failed - elif [[ $ret == 77 || $ret == 127 ]]; then + if [[ $ret -eq 77 ]] || [[ $ret -eq 127 ]]; then echo "$name skipped" echo "$name" >>/skipped-tests { @@ -76,6 +68,14 @@ run_test() { journalctl --unit="$name" --no-hostname -o short-monotonic echo "--- $name end ---" } >>/skipped + elif [[ $ret -ne 0 ]]; then + echo "$name failed with $ret" + echo "$name" >>/failed-tests + { + echo "--- $name begin ---" + journalctl --unit="$name" --no-hostname -o short-monotonic + echo "--- $name end ---" + } >>/failed else echo "$name OK" echo "$name" >>/testok From 0cd488617cb9caa7375ccf62f35c0318d16a55e0 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Mon, 27 May 2024 10:23:38 +0200 Subject: [PATCH 05/13] TEST-36-NUMAPOLICY: Skip when running with sanitizers The test does not work under sanitizers as strace is used. Until the test is fixed to not use strace let's skip it when running with sanitizers. --- test/units/TEST-36-NUMAPOLICY.sh | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/units/TEST-36-NUMAPOLICY.sh b/test/units/TEST-36-NUMAPOLICY.sh index 02ca88f80d..fcd3d6dd89 100755 --- a/test/units/TEST-36-NUMAPOLICY.sh +++ b/test/units/TEST-36-NUMAPOLICY.sh @@ -3,6 +3,11 @@ set -eux set -o pipefail +if [[ -n "${ASAN_OPTIONS:-}" ]]; then + echo "This test does not support running with sanitizers, skipping the test" | tee --append /skipped + exit 77 +fi + # shellcheck disable=SC2317 at_exit() { # shellcheck disable=SC2181 From aae299090773d69377629a65d684c577df238272 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Mon, 27 May 2024 13:38:51 +0200 Subject: [PATCH 06/13] TEST-79-MEMPRESS: Load systemd-asan-env if available Required since we run with DynamicUser=1. --- test/units/TEST-79-MEMPRESS.sh | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/test/units/TEST-79-MEMPRESS.sh b/test/units/TEST-79-MEMPRESS.sh index 4ce73d4c29..2b1de204f7 100755 --- a/test/units/TEST-79-MEMPRESS.sh +++ b/test/units/TEST-79-MEMPRESS.sh @@ -49,7 +49,17 @@ EOF chmod +x "$SCRIPT" -systemd-run -u "$UNIT" -p Type=exec -p ProtectControlGroups=1 -p DynamicUser=1 -p MemoryPressureWatch=on -p MemoryPressureThresholdSec=123ms -p BindPaths=$SCRIPT --wait "$SCRIPT" +systemd-run \ + -u "$UNIT" \ + -p Type=exec \ + -p ProtectControlGroups=1 \ + -p DynamicUser=1 \ + -p MemoryPressureWatch=on \ + -p MemoryPressureThresholdSec=123ms \ + -p BindPaths=$SCRIPT \ + `# Make sanitizers happy when DynamicUser=1 pulls in instrumented systemd NSS modules` \ + -p EnvironmentFile=-/usr/lib/systemd/systemd-asan-env \ + --wait "$SCRIPT" rm "$SCRIPT" From 9029f20b35069d068b8be9fdb16fd6874cd420a0 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Mon, 27 May 2024 19:40:35 +0200 Subject: [PATCH 07/13] TEST-02-UNITTESTS: Pass asan environment to units if it is available Some tests (e.g. test-udev.py) might trigger one of our NSS modules which means LD_PRELOAD has to be configured properly. --- test/units/TEST-02-UNITTESTS.sh | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/units/TEST-02-UNITTESTS.sh b/test/units/TEST-02-UNITTESTS.sh index aac55ea17c..6392425130 100755 --- a/test/units/TEST-02-UNITTESTS.sh +++ b/test/units/TEST-02-UNITTESTS.sh @@ -55,7 +55,13 @@ run_test() { ;; esac - systemd-run --quiet --property Delegate=1 --property "Environment=$environment" --unit="$name" --wait "$test" && ret=0 || ret=$? + systemd-run \ + --quiet \ + --property Delegate=1 \ + --property EnvironmentFile=-/usr/lib/systemd/systemd-asan-env \ + --property "Environment=$environment" \ + --unit="$name" \ + --wait "$test" && ret=0 || ret=$? exec {LOCK_FD}> /lock flock --exclusive ${LOCK_FD} From 4dc76eb770121720db12be1ec83ff13ee4f53dbf Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Thu, 30 May 2024 10:22:51 +0200 Subject: [PATCH 08/13] test-execute: Skip test_exec_mount_apivfs() when running with sanitizers The test fails when running under sanitizers due to missing sanitizer libraries. For now, let's skip the test until we can make the necessary changes to run it under sanitizers. --- src/test/test-execute.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/test/test-execute.c b/src/test/test-execute.c index 191741d97c..daddeb61d0 100644 --- a/src/test/test-execute.c +++ b/src/test/test-execute.c @@ -615,6 +615,7 @@ static void test_exec_inaccessiblepaths(Manager *m) { test(m, "exec-inaccessiblepaths-mount-propagation.service", can_unshare ? 0 : MANAGER_IS_SYSTEM(m) ? EXIT_FAILURE : EXIT_NAMESPACE, CLD_EXITED); } +#if !HAS_FEATURE_ADDRESS_SANITIZER static int on_spawn_io(sd_event_source *s, int fd, uint32_t revents, void *userdata) { char **result = userdata; char buf[4096]; @@ -754,8 +755,10 @@ static int find_libraries(const char *exec, char ***ret) { *ret = TAKE_PTR(libraries); return 0; } +#endif static void test_exec_mount_apivfs(Manager *m) { +#if !HAS_FEATURE_ADDRESS_SANITIZER _cleanup_free_ char *fullpath_touch = NULL, *fullpath_test = NULL, *data = NULL; _cleanup_strv_free_ char **libraries = NULL, **libraries_test = NULL; int r; @@ -801,6 +804,7 @@ static void test_exec_mount_apivfs(Manager *m) { test(m, "exec-mount-apivfs-no.service", can_unshare || !MANAGER_IS_SYSTEM(m) ? 0 : EXIT_NAMESPACE, CLD_EXITED); (void) rm_rf("/tmp/test-exec-mount-apivfs-no/root", REMOVE_ROOT|REMOVE_PHYSICAL); +#endif } static void test_exec_noexecpaths(Manager *m) { From 51e26d236680ff58bdb489bdcdab6e67d0e53510 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Mon, 27 May 2024 13:33:51 +0200 Subject: [PATCH 09/13] test-execute: Skip system call filter tests when sanitizers are used System call filtering is incompatible with sanitizers so let's skip these tests when we're built with sanitizers. --- src/test/test-execute.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/test-execute.c b/src/test/test-execute.c index daddeb61d0..4b8daa46bb 100644 --- a/src/test/test-execute.c +++ b/src/test/test-execute.c @@ -824,7 +824,7 @@ static void test_exec_temporaryfilesystem(Manager *m) { } static void test_exec_systemcallfilter(Manager *m) { -#if HAVE_SECCOMP +#if HAVE_SECCOMP && !HAS_FEATURE_ADDRESS_SANITIZER int r; if (!is_seccomp_available()) { @@ -867,7 +867,7 @@ static void test_exec_systemcallfilter(Manager *m) { } static void test_exec_systemcallerrornumber(Manager *m) { -#if HAVE_SECCOMP +#if HAVE_SECCOMP && !HAS_FEATURE_ADDRESS_SANITIZER int r; if (!is_seccomp_available()) { From f824a33a793b88048a1a3919428d75322a68502d Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Mon, 27 May 2024 13:34:40 +0200 Subject: [PATCH 10/13] test-execute: Load systemd-asan-env environment file if available When DynamicUser= is enabled, we need LD_PRELOAD to be configured correctly as the tests will load systemd's nss module which will complain when built with sanitizers if the sanitizer libraries were not loaded first. --- test/test-execute/exec-ambientcapabilities-dynuser.service | 1 + test/test-execute/exec-dynamicuser-runtimedirectory1.service | 1 + test/test-execute/exec-dynamicuser-runtimedirectory2.service | 1 + test/test-execute/exec-dynamicuser-runtimedirectory3.service | 1 + .../test-execute/exec-dynamicuser-statedir-migrate-step2.service | 1 + test/test-execute/exec-dynamicuser-statedir.service | 1 + test/test-execute/exec-dynamicuser-supplementarygroups.service | 1 + 7 files changed, 7 insertions(+) diff --git a/test/test-execute/exec-ambientcapabilities-dynuser.service b/test/test-execute/exec-ambientcapabilities-dynuser.service index f91164295c..ab815f39a3 100644 --- a/test/test-execute/exec-ambientcapabilities-dynuser.service +++ b/test/test-execute/exec-ambientcapabilities-dynuser.service @@ -8,3 +8,4 @@ Type=oneshot AmbientCapabilities=CAP_CHOWN CAP_SETUID CAP_NET_RAW DynamicUser=yes PrivateUsers=yes +EnvironmentFile=-/usr/lib/systemd/systemd-asan-env diff --git a/test/test-execute/exec-dynamicuser-runtimedirectory1.service b/test/test-execute/exec-dynamicuser-runtimedirectory1.service index d84a96b491..59d3bf0884 100644 --- a/test/test-execute/exec-dynamicuser-runtimedirectory1.service +++ b/test/test-execute/exec-dynamicuser-runtimedirectory1.service @@ -10,3 +10,4 @@ Type=oneshot RuntimeDirectory=test-exec_runtimedirectorypreserve RuntimeDirectoryPreserve=yes DynamicUser=yes +EnvironmentFile=-/usr/lib/systemd/systemd-asan-env diff --git a/test/test-execute/exec-dynamicuser-runtimedirectory2.service b/test/test-execute/exec-dynamicuser-runtimedirectory2.service index d6084b0f5b..6ff9d7503a 100644 --- a/test/test-execute/exec-dynamicuser-runtimedirectory2.service +++ b/test/test-execute/exec-dynamicuser-runtimedirectory2.service @@ -11,3 +11,4 @@ Type=oneshot RuntimeDirectory=test-exec_runtimedirectorypreserve RuntimeDirectoryPreserve=yes DynamicUser=yes +EnvironmentFile=-/usr/lib/systemd/systemd-asan-env diff --git a/test/test-execute/exec-dynamicuser-runtimedirectory3.service b/test/test-execute/exec-dynamicuser-runtimedirectory3.service index fad194183b..cebb819476 100644 --- a/test/test-execute/exec-dynamicuser-runtimedirectory3.service +++ b/test/test-execute/exec-dynamicuser-runtimedirectory3.service @@ -10,3 +10,4 @@ ExecStart=sh -x -c 'touch $$RUNTIME_DIRECTORY/test' Type=oneshot RuntimeDirectory=test-exec_runtimedirectorypreserve DynamicUser=yes +EnvironmentFile=-/usr/lib/systemd/systemd-asan-env diff --git a/test/test-execute/exec-dynamicuser-statedir-migrate-step2.service b/test/test-execute/exec-dynamicuser-statedir-migrate-step2.service index 6fddd21cad..7261f4a174 100644 --- a/test/test-execute/exec-dynamicuser-statedir-migrate-step2.service +++ b/test/test-execute/exec-dynamicuser-statedir-migrate-step2.service @@ -24,3 +24,4 @@ ExecStart=sh -x -c 'test "$$STATE_DIRECTORY" = "%S/test-dynamicuser-migrate:%S/t Type=oneshot DynamicUser=yes StateDirectory=test-dynamicuser-migrate test-dynamicuser-migrate2/hoge +EnvironmentFile=-/usr/lib/systemd/systemd-asan-env diff --git a/test/test-execute/exec-dynamicuser-statedir.service b/test/test-execute/exec-dynamicuser-statedir.service index 734fa209af..636a70259c 100644 --- a/test/test-execute/exec-dynamicuser-statedir.service +++ b/test/test-execute/exec-dynamicuser-statedir.service @@ -83,3 +83,4 @@ ExecStart=sh -x -c 'test "$$STATE_DIRECTORY" = "%S/aaa:%S/aaa/bbb:%S/aaa/ccc:%S/ Type=oneshot DynamicUser=yes StateDirectory=waldo quux/pief aaa/bbb aaa aaa/ccc xxx/yyy:aaa/111 xxx:aaa/222 xxx/zzz:aaa/333 abc:d\:ef +EnvironmentFile=-/usr/lib/systemd/systemd-asan-env diff --git a/test/test-execute/exec-dynamicuser-supplementarygroups.service b/test/test-execute/exec-dynamicuser-supplementarygroups.service index ac6a0fbc20..be1b8f76f2 100644 --- a/test/test-execute/exec-dynamicuser-supplementarygroups.service +++ b/test/test-execute/exec-dynamicuser-supplementarygroups.service @@ -8,3 +8,4 @@ ExecStart=sh -x -c 'for g in $$(id -G); do test "$$g" = "2" && exit 0; done; exi Type=oneshot DynamicUser=yes SupplementaryGroups=1 2 +EnvironmentFile=-/usr/lib/systemd/systemd-asan-env From 6b572e88a353f1d9edd4a87ea24c201ff57faa04 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Tue, 28 May 2024 13:08:23 +0200 Subject: [PATCH 11/13] test-network: Add dirs_exist_ok=True to cp_r() Let's not fail if directories already exist in cp_r(). --- test/test-network/systemd-networkd-tests.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index 07d5f95b34..3636baea6e 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -106,7 +106,7 @@ def cp(src, dst): shutil.copy(src, dst) def cp_r(src, dst): - shutil.copytree(src, dst, copy_function=shutil.copy) + shutil.copytree(src, dst, copy_function=shutil.copy, dirs_exist_ok=True) def mkdir_p(path): os.makedirs(path, exist_ok=True) From aef13ad0294b403993e19b424b26535fb65749f4 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Thu, 16 May 2024 17:18:38 +0200 Subject: [PATCH 12/13] mkosi: Sanitizer improvements - Let's set the environment on the kernel command line so it applies to initrd and main system. - Let's add the necessary wrappers that are also added in test-functions. Unlike test-functions we don't use gcc/clang to get the library path as that requires installing gcc/clang in the initrd. - Let's drop the hack to get journald writing to the console and have it write to kmsg instead. We'll get the output either way. - Stop removing libstdc++ and sanitizer libraries from Arch Linux initrds and other images as it's required by the sanitizer libraries. - Add a workaround for specifying extra meson options for opensuse - Add a leak sanitizer suppression file as a workaround for a false positive leak in verify_selinuxmnt() in libselinux. We do a soname match because the stacktrace can't be properly symbolized on Debian. --- .github/workflows/mkosi.yml | 1 + mkosi.conf | 10 +- mkosi.conf.d/20-sanitizers.conf | 19 +++ mkosi.images/exitrd/mkosi.conf.d/10-arch.conf | 5 - .../minimal-base/mkosi.conf.d/10-arch.conf | 5 - mkosi.images/system/initrd/mkosi.conf | 4 + mkosi.images/system/mkosi.conf | 7 + .../10-opensuse/mkosi.build.chroot | 4 +- .../lib/systemd/leak-sanitizer-suppressions | 1 + .../system/iscsi-init.service.d/asan.conf | 7 + mkosi.images/system/mkosi.postinst.chroot | 42 ------ mkosi.images/system/mkosi.sanitizers.chroot | 130 ++++++++++++++++++ 12 files changed, 175 insertions(+), 60 deletions(-) create mode 100644 mkosi.conf.d/20-sanitizers.conf create mode 100644 mkosi.images/system/initrd/mkosi.conf create mode 100644 mkosi.images/system/mkosi.extra/usr/lib/systemd/leak-sanitizer-suppressions create mode 100644 mkosi.images/system/mkosi.extra/usr/lib/systemd/system/iscsi-init.service.d/asan.conf create mode 100755 mkosi.images/system/mkosi.sanitizers.chroot diff --git a/.github/workflows/mkosi.yml b/.github/workflows/mkosi.yml index be5f1edfee..a3be3e99b1 100644 --- a/.github/workflows/mkosi.yml +++ b/.github/workflows/mkosi.yml @@ -123,6 +123,7 @@ jobs: ToolsTreeDistribution=fedora # TODO: Drop once https://bugs.launchpad.net/ubuntu/+source/linux/+bug/2038777 is fixed in Github Actions QemuFirmware=uefi + QemuMem=4G # We build with debuginfo so there's no point in mounting the sources into the machine. RuntimeBuildSources=no EOF diff --git a/mkosi.conf b/mkosi.conf index 2da8804a7e..8ad0cb0d0f 100644 --- a/mkosi.conf +++ b/mkosi.conf @@ -10,13 +10,9 @@ MinimumVersion=23~devel @CacheDirectory=build/mkosi.cache [Content] -# Prevent ASAN warnings when building the image and ship the real ASAN options prefixed with MKOSI_. -Environment=ASAN_OPTIONS=verify_asan_link_order=false - MKOSI_ASAN_OPTIONS=strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1:disable_coredump=0:use_madv_dontdump=1 - MKOSI_UBSAN_OPTIONS=print_stacktrace=1:print_summary=1:halt_on_error=1 - # The kernel versions in CentOS Stream 9 and Ubuntu 22.04 don't support orphan_file, but later - # versions of mkfs.ext4 enabled it by default, so we disable it explicitly. - SYSTEMD_REPART_MKFS_OPTIONS_EXT4="-O ^orphan_file" +# The kernel versions in CentOS Stream 9 and Ubuntu 22.04 don't support orphan_file, but later +# versions of mkfs.ext4 enabled it by default, so we disable it explicitly. +Environment=SYSTEMD_REPART_MKFS_OPTIONS_EXT4="-O ^orphan_file" @SELinuxRelabel=no BuildSourcesEphemeral=yes diff --git a/mkosi.conf.d/20-sanitizers.conf b/mkosi.conf.d/20-sanitizers.conf new file mode 100644 index 0000000000..235b233e1a --- /dev/null +++ b/mkosi.conf.d/20-sanitizers.conf @@ -0,0 +1,19 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +[Match] +Environment=SANITIZERS + +[Content] +# Set verify_asan_link_order=0 to prevent ASAN warnings when building the image and make sure the real ASAN +# options are set when booting the image. +# Set intercept_tls_get_addr=0 to work around leak sanitizer segmentation fault in test-dlopen-so on CentOS +# Stream 9. +# TODO: Drop intercept_tls_get_addr=0 when we remove CentOS Stream 9 builds. +Environment=ASAN_OPTIONS=verify_asan_link_order=0:intercept_tls_get_addr=0 +KernelCommandLine= + ASAN_OPTIONS=strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1:disable_coredump=0:use_madv_dontdump=1 + systemd.setenv=ASAN_OPTIONS=strict_string_checks=1:detect_stack_use_after_return=1:check_initialization_order=1:strict_init_order=1:disable_coredump=0:use_madv_dontdump=1 + UBSAN_OPTIONS=print_stacktrace=1:print_summary=1:halt_on_error=1 + systemd.setenv=UBSAN_OPTIONS=print_stacktrace=1:print_summary=1:halt_on_error=1 + LSAN_OPTIONS=suppressions=/usr/lib/systemd/leak-sanitizer-suppressions + systemd.setenv=LSAN_OPTIONS=suppressions=/usr/lib/systemd/leak-sanitizer-suppressions diff --git a/mkosi.images/exitrd/mkosi.conf.d/10-arch.conf b/mkosi.images/exitrd/mkosi.conf.d/10-arch.conf index 25d20887ff..c8b1904f6f 100644 --- a/mkosi.images/exitrd/mkosi.conf.d/10-arch.conf +++ b/mkosi.images/exitrd/mkosi.conf.d/10-arch.conf @@ -15,11 +15,6 @@ RemoveFiles= /usr/lib/libgomp.so* /usr/lib/libgphobos.so* /usr/lib/libobjc.so* - /usr/lib/libasan.so* - /usr/lib/libtsan.so* - /usr/lib/liblsan.so* - /usr/lib/libubsan.so* - /usr/lib/libstdc++.so* /usr/lib/libgdruntime.so* # Remove all files that are only required for development. diff --git a/mkosi.images/minimal-base/mkosi.conf.d/10-arch.conf b/mkosi.images/minimal-base/mkosi.conf.d/10-arch.conf index 30e8fda59e..9b033975d6 100644 --- a/mkosi.images/minimal-base/mkosi.conf.d/10-arch.conf +++ b/mkosi.images/minimal-base/mkosi.conf.d/10-arch.conf @@ -17,11 +17,6 @@ RemoveFiles= /usr/lib/libgomp.so* /usr/lib/libgphobos.so* /usr/lib/libobjc.so* - /usr/lib/libasan.so* - /usr/lib/libtsan.so* - /usr/lib/liblsan.so* - /usr/lib/libubsan.so* - /usr/lib/libstdc++.so* /usr/lib/libgdruntime.so* # Remove all files that are only required for development. diff --git a/mkosi.images/system/initrd/mkosi.conf b/mkosi.images/system/initrd/mkosi.conf new file mode 100644 index 0000000000..c54d1a24ee --- /dev/null +++ b/mkosi.images/system/initrd/mkosi.conf @@ -0,0 +1,4 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +[Content] +PostInstallationScripts=../mkosi.sanitizers.chroot diff --git a/mkosi.images/system/mkosi.conf b/mkosi.images/system/mkosi.conf index f543b6410f..1c2e0c553b 100644 --- a/mkosi.images/system/mkosi.conf +++ b/mkosi.images/system/mkosi.conf @@ -27,6 +27,13 @@ ExtraTrees= %O/minimal-base:/usr/share/TEST-13-NSPAWN-container-template %O/exitrd:/exitrd +PostInstallationScripts=mkosi.sanitizers.chroot + +InitrdPackages= + findutils + grep + sed + Packages= acl attr diff --git a/mkosi.images/system/mkosi.conf.d/10-opensuse/mkosi.build.chroot b/mkosi.images/system/mkosi.conf.d/10-opensuse/mkosi.build.chroot index 8b6fc7ab13..4e8f982176 100755 --- a/mkosi.images/system/mkosi.conf.d/10-opensuse/mkosi.build.chroot +++ b/mkosi.images/system/mkosi.conf.d/10-opensuse/mkosi.build.chroot @@ -49,6 +49,8 @@ build() { IFS= # TODO: Replace meson_build and meson_install overrides with "--undefine __meson_verbose" once # https://github.com/mesonbuild/meson/pull/12835 is available. + # TODO: Replace __meson_auto_features override with meson_extra_configure_options once the suse spec + # starts to use it. # shellcheck disable=SC2046 rpmbuild \ -bb \ @@ -69,7 +71,7 @@ build() { --define "build_cflags $(rpm --eval %build_cflags) $EXTRA_CFLAGS" \ --define "meson_build %{shrink:%{__meson} compile -C %{_vpath_builddir} -j %{_smp_build_ncpus} %{nil}}" \ --define "meson_install %{shrink:DESTDIR=%{buildroot} %{__meson} install -C %{_vpath_builddir} --no-rebuild --quiet %{nil}}" \ - --define "meson_extra_configure_options -D mode=developer -D b_sanitize=${SANITIZERS:-none}" \ + --define "__meson_auto_features auto -D mode=developer -D b_sanitize=${SANITIZERS:-none}" \ --define "__os_install_post /usr/lib/rpm/brp-suse %{nil}" \ --define "__elf_exclude_path ^/usr/lib/systemd/tests/unit-tests/.*$" \ --define "__script_requires %{nil}" \ diff --git a/mkosi.images/system/mkosi.extra/usr/lib/systemd/leak-sanitizer-suppressions b/mkosi.images/system/mkosi.extra/usr/lib/systemd/leak-sanitizer-suppressions new file mode 100644 index 0000000000..639abb8f3f --- /dev/null +++ b/mkosi.images/system/mkosi.extra/usr/lib/systemd/leak-sanitizer-suppressions @@ -0,0 +1 @@ +leak:libselinux diff --git a/mkosi.images/system/mkosi.extra/usr/lib/systemd/system/iscsi-init.service.d/asan.conf b/mkosi.images/system/mkosi.extra/usr/lib/systemd/system/iscsi-init.service.d/asan.conf new file mode 100644 index 0000000000..ebf7899a78 --- /dev/null +++ b/mkosi.images/system/mkosi.extra/usr/lib/systemd/system/iscsi-init.service.d/asan.conf @@ -0,0 +1,7 @@ +# SPDX-License-Identifier: LGPL-2.1-or-later + +# The iscsi-init.service calls `sh` which might, in certain circumstances, pull in instrumented systemd NSS +# modules causing `sh` to fail. Avoid the issue by setting LD_PRELOAD to load the sanitizer libraries if +# needed. +[Service] +EnvironmentFile=-/usr/lib/systemd/systemd-asan-env diff --git a/mkosi.images/system/mkosi.postinst.chroot b/mkosi.images/system/mkosi.postinst.chroot index 15f268a20a..397884b720 100755 --- a/mkosi.images/system/mkosi.postinst.chroot +++ b/mkosi.images/system/mkosi.postinst.chroot @@ -2,48 +2,6 @@ # SPDX-License-Identifier: LGPL-2.1-or-later set -e -if [ -n "$SANITIZERS" ]; then - LD_PRELOAD=$(ldd /usr/lib/systemd/systemd | grep libasan.so | awk '{print $3}') - - mkdir -p /etc/systemd/system.conf.d - - cat >/etc/systemd/system.conf.d/10-asan.conf </etc/systemd/system/systemd-journald.service.d/10-stdout-tty.conf </etc/systemd/system/console-getty.service.d/10-no-vhangup.conf < 50s when built with sanitizers so let's not run it by default. - systemctl mask systemd-hwdb-update.service -fi - if command -v authselect >/dev/null; then # authselect 1.5.0 renamed the minimal profile to the local profile without keeping backwards compat so # let's use the new name if it exists. diff --git a/mkosi.images/system/mkosi.sanitizers.chroot b/mkosi.images/system/mkosi.sanitizers.chroot new file mode 100755 index 0000000000..48c5d147aa --- /dev/null +++ b/mkosi.images/system/mkosi.sanitizers.chroot @@ -0,0 +1,130 @@ +#!/bin/bash +# SPDX-License-Identifier: LGPL-2.1-or-later +set -e + +if [[ -z "$SANITIZERS" ]]; then + exit 0 +fi + +# Sanitizers log to stderr by default. However, journald's stderr is connected to /dev/null, so we lose +# all the sanitizer logs. To rectify that, let's connect journald's stdout to kmsg so that the sanitizer +# failures end up in the journal. +mkdir -p /etc/systemd/system/systemd-journald.service.d +cat >/etc/systemd/system/systemd-journald.service.d/10-stdout-tty.conf < 50s when built with sanitizers so let's not run it by default. +systemctl mask systemd-hwdb-update.service + +ASAN_RT_PATH="$(grep libasan.so < <(ldd /usr/lib/systemd/systemd) | cut -d ' ' -f 3)" +if [[ -z "$ASAN_RT_PATH" ]]; then + ASAN_RT_PATH="$(grep libclang_rt.asan < <(ldd /usr/lib/systemd/systemd) | cut -d ' ' -f 3)" + + # As clang's ASan DSO is usually in a non-standard path, let's check if + # the environment is set accordingly. If not, warn the user and exit. + # We're not setting the LD_LIBRARY_PATH automagically here, because + # user should encounter (and fix) the same issue when running the unit + # tests (meson test) + if ldd /usr/lib/systemd/systemd | grep -q "libclang_rt.asan.*not found"; then + echo >&2 "clang's ASan DSO libclang_rt.asan is not present in the runtime library path" + exit 1 + fi +fi +if [[ -z "$ASAN_RT_PATH" ]]; then + echo >&2 "systemd is not linked against the ASan DSO" + echo >&2 "gcc does this by default, for clang compile with -shared-libasan" + exit 1 +fi + +wrap=( + /usr/lib/polkit-1/polkitd + /usr/libexec/polkit-1/polkitd + agetty + btrfs + capsh + chgrp + chown + cryptsetup + curl + dbus-broker-launch + dbus-daemon + delv + dhcpd + dig + dmsetup + dnsmasq + findmnt + getent + getfacl + id + integritysetup + iscsid + kpartx + logger + login + ls + lsblk + lvm + mdadm + mkfs.btrfs + mkfs.erofs + mkfs.ext4 + mkfs.vfat + mkfs.xfs + mksquashfs + mkswap + multipath + multipathd + nvme + p11-kit + pkill + ps + setfacl + setpriv + sshd + stat + su + tar + tgtd + useradd + userdel + veritysetup +) + +for bin in "${wrap[@]}"; do + if ! command -v "$bin" >/dev/null; then + continue + fi + + if [[ "$bin" == getent ]]; then + enable_lsan=1 + else + enable_lsan=0 + fi + + target="$(command -v "$bin")" + + mv "$target" "$target.orig" + + cat >"$target" </usr/lib/systemd/systemd-asan-env < Date: Thu, 16 May 2024 17:20:24 +0200 Subject: [PATCH 13/13] ci: Build with sanitizers in mkosi --- .github/workflows/mkosi.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/mkosi.yml b/.github/workflows/mkosi.yml index a3be3e99b1..3f75ef54aa 100644 --- a/.github/workflows/mkosi.yml +++ b/.github/workflows/mkosi.yml @@ -117,6 +117,7 @@ jobs: WITH_DEBUG=1 # Enabling optimizations significantly speeds up integration tests. OPTIMIZATION=g + SANITIZERS=address,undefined [Host] ToolsTree=default