From 6bc9ed168849f93ecf8c417c1521b1d5225ffe62 Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Thu, 3 Mar 2022 20:30:43 +0100 Subject: [PATCH 01/41] test: check systemd RPM macros Make sure our RPM macros work as intended. Based on the original PR (#16464) by Mikhail Novosyolov. Co-authored-by: Mikhail Novosyolov (cherry picked from commit 55c09511e13c6a57ffe64bef4a9d0a00f34d37d9) Related: #2013213 --- .github/workflows/unit_tests.sh | 1 + .semaphore/semaphore-runner.sh | 2 +- test/meson.build | 16 ++++ test/test-rpm-macros.sh | 162 ++++++++++++++++++++++++++++++++ 4 files changed, 180 insertions(+), 1 deletion(-) create mode 100755 test/test-rpm-macros.sh diff --git a/.github/workflows/unit_tests.sh b/.github/workflows/unit_tests.sh index 9c7beb6d19e..f41b070e57a 100755 --- a/.github/workflows/unit_tests.sh +++ b/.github/workflows/unit_tests.sh @@ -20,6 +20,7 @@ ADDITIONAL_DEPS=( perl python3-libevdev python3-pyparsing + rpm zstd ) diff --git a/.semaphore/semaphore-runner.sh b/.semaphore/semaphore-runner.sh index d02b449e0eb..6ccf271a82f 100755 --- a/.semaphore/semaphore-runner.sh +++ b/.semaphore/semaphore-runner.sh @@ -42,7 +42,7 @@ apt-get -q --allow-releaseinfo-change update apt-get -y dist-upgrade apt-get install -y eatmydata # The following four are needed as long as these deps are not covered by Debian's own packaging -apt-get install -y fdisk tree libfdisk-dev libp11-kit-dev libssl-dev libpwquality-dev +apt-get install -y fdisk tree libfdisk-dev libp11-kit-dev libssl-dev libpwquality-dev rpm apt-get purge --auto-remove -y unattended-upgrades systemctl unmask systemd-networkd systemctl enable systemd-networkd diff --git a/test/meson.build b/test/meson.build index 8de1043e170..04ae9ebc780 100644 --- a/test/meson.build +++ b/test/meson.build @@ -163,6 +163,22 @@ endif ############################################################ +rpm = find_program('rpm', required : false) +rpmspec = find_program('rpmspec', required : false) +test_rpm_macros = find_program('test-rpm-macros.sh') + +if rpm.found() and rpmspec.found() + if want_tests != 'false' + test('test-rpm-macros', + test_rpm_macros, + args : [project_build_root]) + endif +else + message('Skipping test-rpm-macros since rpm and/or rpmspec are not available') +endif + +############################################################ + if want_tests != 'false' and dmi_arches.contains(host_machine.cpu_family()) udev_dmi_memory_id_test = find_program('udev-dmi-memory-id-test.sh') diff --git a/test/test-rpm-macros.sh b/test/test-rpm-macros.sh new file mode 100755 index 00000000000..5843b72346b --- /dev/null +++ b/test/test-rpm-macros.sh @@ -0,0 +1,162 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: LGPL-2.1-or-later +# This test makes some basic checks that RPM macros work correctly. +# RPM is a simple C program available on different Linux distros, not only RPM-based ones, +# and even BSD systems, so it must not be a problem to require it. +# rpmspec utility is required (so this test will work with RPM 4 but won't work with RPM 5). +set -eu + +BUILD_DIR="${1:?Missing argument: build directory}" +RPM_MACROS_FILE="${BUILD_DIR:?}/src/rpm/macros.systemd" + +if ! command -v rpm >/dev/null || ! command -v rpmspec >/dev/null; then + echo >&2 "Missing necessary utilities (rpm, rpmspec), can't continue" + exit 1 +fi + +if [[ ! -f "${RPM_MACROS_FILE:?}" ]]; then + echo "RPM macros file not found in $RPM_MACROS_FILE!" + exit 1 +fi + +at_exit() { + if [[ -v WORK_DIR && -d "$WORK_DIR" ]]; then + rm -frv "$WORK_DIR" + fi +} + +trap at_exit EXIT + +WORK_DIR="$(mktemp -d)" +RPM_SPEC="$(mktemp "$WORK_DIR/systemd-test-rpm-macros-XXX.spec")" +TEMP_LOG="$(mktemp "$WORK_DIR/out-XXX.log")" + +die() { + echo >&2 "${1:?}" + exit 1 +} + +mk_mini_spec() { + cat >"${RPM_SPEC:?}" <>"$RPM_SPEC" +: >"$TEMP_LOG" +rpmspec --parse "$RPM_SPEC" | tee "$TEMP_LOG" +for i in post preun postun; do + echo "== Requires($i) ==" + grep "^Requires($i): systemd$" "$TEMP_LOG" +done + +echo "=== Test %systemd_ordering ===" +mk_mini_spec +echo "%systemd_ordering" >>"$RPM_SPEC" +: >"$TEMP_LOG" +rpmspec --parse "$RPM_SPEC" | tee "$TEMP_LOG" +for i in post preun postun; do + echo "== OrderWithRequires($i) ==" + grep "^OrderWithRequires($i): systemd$" "$TEMP_LOG" +done + +echo "=== Test macros requiring an argument without specifying such argument ===" +for i in \ + systemd_post \ + systemd_preun \ + systemd_postun \ + systemd_postun_with_restart \ + systemd_user_preun \ + systemd_user_postun \ + systemd_user_postun_with_restart \ + tmpfiles_create \ + tmpfiles_create_package \ + sysusers_create \ + sysusers_create_package +do + echo "== Macro: $i ==" + mk_mini_spec + echo "%${i}" >>"$RPM_SPEC" + if rpmspec --parse "$RPM_SPEC"; then + die "Unexpected pass with macro $i (no arguments)" + fi +done + +echo "=== Test macros requiring two arguments ===" +for i in \ + tmpfiles_create_package \ + sysusers_create_package +do + echo "== Macro: $i ==" + # Test with an incorrect number of arguments (0, 1, 3) + for args in "" "arg1" "arg1 arg2 arg3"; do + mk_mini_spec + echo "%${i} $args" >>"$RPM_SPEC" + if rpmspec --parse "$RPM_SPEC"; then + die "Unexpected pass with macro $i (arguments: $args)" + fi + done + + # Test with the correct number of arguments (2) + mk_mini_spec + echo "%${i} arg1 arg2" >>"$RPM_SPEC" + if ! rpmspec --parse "$RPM_SPEC"; then + die "Unexpected fail with macro $i (arguments: $args)" + fi +done + + +# Test that: +# - *_create_package macros do work correctly +# - shell syntax is correct (https://github.com/systemd/systemd/commit/93406fd37) +# - RPM macros, loaded from macros.in, are actually expanded +echo "=== Test %*_create_package macros ===" +for i in sysusers tmpfiles; do + echo "== Macro: ${i}_create_package ==" + + PKG_DATA_FILE="$(mktemp "$WORK_DIR/pkg-data-XXX")" + EXP_OUT="$(mktemp "$WORK_DIR/exp-out-XXX.log")" + CONF_DIR="$(pkg-config --variable="${i}dir" systemd)" + EXTRA_ARGS=() + + if [[ "$i" == tmpfiles ]]; then + EXTRA_ARGS+=("--create") + fi + + echo "TEST_DATA" >"$PKG_DATA_FILE" + mk_mini_spec + echo "%${i}_create_package TEST_NAME ${PKG_DATA_FILE}" >>"$RPM_SPEC" + + cat >"$EXP_OUT" <"$TEMP_LOG" + rpmspec --parse "$RPM_SPEC" | tee "$TEMP_LOG" + diff "$EXP_OUT" <(grep -A1 -B1 '^TEST_DATA$' "$TEMP_LOG") + + rm -f "$PKG_DATA_FILE" +done From 6513dc2dd2a618782ea5a911612fcd507ea071dc Mon Sep 17 00:00:00 2001 From: Luca Boccassi Date: Wed, 12 Jan 2022 22:38:22 +0000 Subject: [PATCH 02/41] test: do not assume x86-64 arch in TEST-58-REPART (cherry picked from commit 8e65d93e85f06e3f28b0b7a6e33b041ddf119917) Related: #2013213$ --- test/units/testsuite-58.sh | 76 ++++++++++++++++++++++++++++++++------ 1 file changed, 65 insertions(+), 11 deletions(-) diff --git a/test/units/testsuite-58.sh b/test/units/testsuite-58.sh index 78c25051a2d..4b3c984c84d 100755 --- a/test/units/testsuite-58.sh +++ b/test/units/testsuite-58.sh @@ -11,6 +11,60 @@ fi export SYSTEMD_LOG_LEVEL=debug export PAGER=cat +machine="$(uname -m)" +if [ "${machine}" = "x86_64" ]; then + root_guid=4f68bce3-e8cd-4db1-96e7-fbcaf984b709 + root_uuid=60F33797-1D71-4DCB-AA6F-20564F036CD0 + usr_guid=8484680c-9521-48c6-9c11-b0720656f69e + usr_uuid=7E3369DD-D653-4513-ADF5-B993A9F20C16 + architecture="x86-64" +elif [ "${machine}" = "i386" ] || [ "${machine}" = "i686" ] || [ "${machine}" = "x86" ]; then + root_guid=44479540-f297-41b2-9af7-d131d5f0458a + root_uuid=02b4253f-29a4-404e-8972-1669d3b03c87 + usr_guid=75250d76-8cc6-458e-bd66-bd47cc81a812 + usr_uuid=7b42ffb0-b0e1-4395-b20b-c78f4a571648 + architecture="x86" +elif [ "${machine}" = "aarch64" ] || [ "${machine}" = "aarch64_be" ] || [ "${machine}" = "armv8b" ] || [ "${machine}" = "armv8l" ]; then + root_guid=b921b045-1df0-41c3-af44-4c6f280d3fae + root_uuid=055d0227-53a6-4033-85c3-9a5973eff483 + usr_guid=b0e01050-ee5f-4390-949a-9101b17104e9 + usr_uuid=fce3c75e-d6a4-44c0-87f0-4c105183fb1f + architecture="arm64" +elif [ "${machine}" = "arm" ]; then + root_guid=69dad710-2ce4-4e3c-b16c-21a1d49abed3 + root_uuid=567da89e-8de2-4499-8d10-18f212dff034 + usr_guid=7d0359a3-02b3-4f0a-865c-654403e70625 + usr_uuid=71e93dc2-5073-42cb-8a84-a354e64d8966 + architecture="arm" +elif [ "${machine}" = "loongarch64" ]; then + root_guid=77055800-792c-4f94-b39a-98c91b762bb6 + root_uuid=d8efc2d2-0133-41e4-bdcb-3b9f4cfddde8 + usr_guid=e611c702-575c-4cbe-9a46-434fa0bf7e3f + usr_uuid=031ffa75-00bb-49b6-a70d-911d2d82a5b7 + architecture="loongarch64" +elif [ "${machine}" = "ia64" ]; then + root_guid=993d8d3d-f80e-4225-855a-9daf8ed7ea97 + root_uuid=dcf33449-0896-4ea9-bc24-7d58aeef522d + usr_guid=4301d2a6-4e3b-4b2a-bb94-9e0b2c4225ea + usr_uuid=bc2bcce7-80d6-449a-85cc-637424ce5241 + architecture="ia64" +elif [ "${machine}" = "s390x" ]; then + root_guid=5eead9a9-fe09-4a1e-a1d7-520d00531306 + root_uuid=7ebe0c85-e27e-48ec-b164-f4807606232e + usr_guid=8a4f5770-50aa-4ed3-874a-99b710db6fea + usr_uuid=51171d30-35cf-4a49-b8b5-9478b9b796a5 + architecture="s390x" +elif [ "${machine}" = "ppc64le" ]; then + root_guid=c31c45e6-3f39-412e-80fb-4809c4980599 + root_uuid=061e67a1-092f-482f-8150-b525d50d6654 + usr_guid=15bb03af-77e7-4d4a-b12b-c0d084f7491c + usr_uuid=c0d0823b-8040-4c7c-a629-026248e297fb + architecture="ppc64-le" +else + echo "Unexpected uname -m: ${machine} in testsuite-58.sh, please fix me" + exit 1 +fi + rm -f /var/tmp/testsuite-58.img /var/tmp/testsuite-58.2.img /tmp/testsuite-58.dump mkdir -p /tmp/testsuite-58-defs/ @@ -25,7 +79,7 @@ EOF cat >/tmp/testsuite-58-defs/usr.conf </tmp/testsuite-58-defs/root.conf </tmp/testsuite-58-defs/usr.conf </tmp/testsuite-58-defs/root.conf </tmp/testsuite-58.3-defs/root.conf </tmp/testsuite-58-issue-21817-defs/test.conf < Date: Mon, 7 Feb 2022 14:35:40 +0100 Subject: [PATCH 03/41] tests: add repart tests for block devices with 1024, 2048, 4096 byte sector sizes let's make sure repart works with 4K drives and exotic sector sizes. (cherry picked from commit 2cd341afb96486bd4afcdba23f02a27631c5b8db) Related: #2013213 --- test/units/testsuite-58.sh | 42 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) diff --git a/test/units/testsuite-58.sh b/test/units/testsuite-58.sh index 4b3c984c84d..7aed965fb44 100755 --- a/test/units/testsuite-58.sh +++ b/test/units/testsuite-58.sh @@ -189,6 +189,48 @@ grep -qF 'p2 : start= 104448, size= 100319,' /tmp/testsuite-58-issue-2 rm /tmp/testsuite-58-issue-21817.img /tmp/testsuite-58-issue-21817.dump rm -r /tmp/testsuite-58-issue-21817-defs/ +testsector() +{ + echo "Running sector test with sector size $1..." + + mkdir -p /tmp/testsuite-58-sector + cat > /tmp/testsuite-58-sector/a.conf < /tmp/testsuite-58-sector/b.conf < /tmp/testsuite-58-sector/c.conf <= 512 and <= PAGE_SIZE, and +# must be powers of 2. Which leaves exactly four different ones to test on +# typical hardware +testsector 512 +testsector 1024 +testsector 2048 +testsector 4096 + echo OK >/testok exit 0 From 5bc34036bc5d83093f2327a41a86ec3d6fed482d Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Fri, 25 Feb 2022 15:09:07 +0100 Subject: [PATCH 04/41] test: accept both unpadded and padded partition sizes Since util-linux/util-linux@921c7da55ec78350e4067b3fd6b7de6f299106ee libfdisk aligns the last partition (on GPT) for optimal I/O. Let's account for that. Fixes: #22606 (cherry picked from commit d490188b8f6da658d8086dd53b7db95735e5cca1) Related: #2013213 --- test/units/testsuite-58.sh | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/units/testsuite-58.sh b/test/units/testsuite-58.sh index 7aed965fb44..f1b690a71ff 100755 --- a/test/units/testsuite-58.sh +++ b/test/units/testsuite-58.sh @@ -184,7 +184,8 @@ sfdisk --dump "$LOOP" | tee /tmp/testsuite-58-issue-21817.dump losetup -d "$LOOP" grep -qiF "p1 : start= 2048, size= 102400, type=${root_guid}," /tmp/testsuite-58-issue-21817.dump -grep -qF 'p2 : start= 104448, size= 100319,' /tmp/testsuite-58-issue-21817.dump +# Accept both unpadded (pre-v2.38 util-linux) and padded (v2.38+ util-linux) sizes +grep -qE "p2 : start= 104448, size= (100319| 98304)," /tmp/testsuite-58-issue-21817.dump rm /tmp/testsuite-58-issue-21817.img /tmp/testsuite-58-issue-21817.dump rm -r /tmp/testsuite-58-issue-21817-defs/ From 89e4b48a53b6c7e23b996b8773d41a9323d921aa Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Wed, 9 Feb 2022 22:35:03 +0100 Subject: [PATCH 05/41] test: lvm 2.03.15 dropped the static autoactivation so install the respective generator only if we're running with older lvm versions. See: https://sourceware.org/git/?p=lvm2.git;a=commit;h=ee8fb0310c53ed003a43b324c99cdfd891dd1a7c (cherry picked from commit d10d562bd4b9f93130fb2b23f2b0d0d4126ea7d4) Related: #2013213 --- test/test-functions | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/test/test-functions b/test/test-functions index 4827b6bedf0..dcc893733c3 100644 --- a/test/test-functions +++ b/test/test-functions @@ -973,16 +973,19 @@ install_lvm() { image_install lvm image_install "${ROOTLIBDIR:?}"/system/lvm2-lvmpolld.{service,socket} image_install "${ROOTLIBDIR:?}"/system/{blk-availability,lvm2-monitor}.service - image_install "${ROOTLIBDIR:?}"/system-generators/lvm2-activation-generator image_install -o "/lib/tmpfiles.d/lvm2.conf" if get_bool "$LOOKS_LIKE_DEBIAN"; then inst_rules 56-lvm.rules 69-lvm-metad.rules else # Support the new udev autoactivation introduced in lvm 2.03.14 # https://sourceware.org/git/?p=lvm2.git;a=commit;h=67722b312390cdab29c076c912e14bd739c5c0f6 + # Static autoactivation (via lvm2-activation-generator) was dropped + # in lvm 2.03.15 + # https://sourceware.org/git/?p=lvm2.git;a=commit;h=ee8fb0310c53ed003a43b324c99cdfd891dd1a7c if [[ -f /lib/udev/rules.d/69-dm-lvm.rules ]]; then inst_rules 11-dm-lvm.rules 69-dm-lvm.rules else + image_install "${ROOTLIBDIR:?}"/system-generators/lvm2-activation-generator image_install "${ROOTLIBDIR:?}"/system/lvm2-pvscan@.service inst_rules 11-dm-lvm.rules 69-dm-lvm-metad.rules fi From f91de023139733e1b20e494cc14873bcdeeddb8c Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Thu, 10 Feb 2022 12:29:53 +0100 Subject: [PATCH 06/41] test: accept GC'ed units in newer LVM Since lvm 2.03.15 the transient units are started without `-r`, thus disappearing once they finish and breaking the test (which expects them to remain loaded after finishing). Let's accept `LoadState=not-found` as a valid result as well to fix this. Follow-up to: d10d562bd4b9f93130fb2b23f2b0d0d4126ea7d4 See: https://sourceware.org/git/?p=lvm2.git;a=commit;h=fbd8b0cf43dc67f51f86f060dce748f446985855 (cherry picked from commit b034f02c628057c30a2136289a1b388a6fb9a737) Related: #2013213 --- test/units/testsuite-64.sh | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/units/testsuite-64.sh b/test/units/testsuite-64.sh index f75382d90a6..dc8b263b100 100755 --- a/test/units/testsuite-64.sh +++ b/test/units/testsuite-64.sh @@ -96,6 +96,14 @@ helper_wait_for_lvm_activate() { if [[ "$(systemctl show -P SubState "$lvm_activate_svc")" == exited ]]; then return 0 fi + else + # Since lvm 2.03.15 the lvm-activate transient unit no longer remains + # after finishing, so we have to treat non-existent units as a success + # as well + # See: https://sourceware.org/git/?p=lvm2.git;a=commit;h=fbd8b0cf43dc67f51f86f060dce748f446985855 + if [[ "$(systemctl show -P LoadState "$lvm_activate_svc")" == not-found ]]; then + return 0 + fi fi sleep .5 From 0b8c4107e128dc62890d049235fa8d50c9bdaf22 Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Tue, 1 Mar 2022 17:04:13 +0000 Subject: [PATCH 07/41] shared: Add more dlopen() tests Add dlopen_dw(), dlopen_elf() and dlopen_pcre2() to the dlopen test. To enable adding dlopen_pcre2(), we move pcre2-dlopen.h/c from src/journal to src/shared. (cherry picked from commit ee48779e05831a0ec5e1ba5e7ed5fe92aaca1d9e) Related: #2013213 --- src/journal/meson.build | 2 -- src/shared/elf-util.c | 4 ++-- src/shared/elf-util.h | 3 +++ src/shared/meson.build | 2 ++ src/{journal => shared}/pcre2-dlopen.c | 0 src/{journal => shared}/pcre2-dlopen.h | 0 src/test/test-dlopen-so.c | 11 +++++++++++ 7 files changed, 18 insertions(+), 4 deletions(-) rename src/{journal => shared}/pcre2-dlopen.c (100%) rename src/{journal => shared}/pcre2-dlopen.h (100%) diff --git a/src/journal/meson.build b/src/journal/meson.build index eb66bfd584a..270592f2aca 100644 --- a/src/journal/meson.build +++ b/src/journal/meson.build @@ -49,8 +49,6 @@ systemd_cat_sources = files('cat.c') journalctl_sources = files(''' journalctl.c - pcre2-dlopen.c - pcre2-dlopen.h '''.split()) if install_sysconfdir_samples diff --git a/src/shared/elf-util.c b/src/shared/elf-util.c index 4d93e7eabaa..6d9fcfbbf2a 100644 --- a/src/shared/elf-util.c +++ b/src/shared/elf-util.c @@ -80,7 +80,7 @@ unsigned int (*sym_elf_version)(unsigned int); GElf_Phdr *(*sym_gelf_getphdr)(Elf *, int, GElf_Phdr *); size_t (*sym_gelf_getnote)(Elf_Data *, size_t, GElf_Nhdr *, size_t *, size_t *); -static int dlopen_dw(void) { +int dlopen_dw(void) { int r; r = dlopen_many_sym_or_warn( @@ -123,7 +123,7 @@ static int dlopen_dw(void) { return 1; } -static int dlopen_elf(void) { +int dlopen_elf(void) { int r; r = dlopen_many_sym_or_warn( diff --git a/src/shared/elf-util.h b/src/shared/elf-util.h index cf3d9be1284..b28e64cea65 100644 --- a/src/shared/elf-util.h +++ b/src/shared/elf-util.h @@ -4,6 +4,9 @@ #include "json.h" #if HAVE_ELFUTILS +int dlopen_dw(void); +int dlopen_elf(void); + /* Parse an ELF object in a forked process, so that errors while iterating over * untrusted and potentially malicious data do not propagate to the main caller's process. * If fork_disable_dump, the child process will not dump core if it crashes. */ diff --git a/src/shared/meson.build b/src/shared/meson.build index 5dc58a863d4..006310a9171 100644 --- a/src/shared/meson.build +++ b/src/shared/meson.build @@ -241,6 +241,8 @@ shared_sources = files(''' parse-argument.h parse-socket-bind-item.c parse-socket-bind-item.h + pcre2-dlopen.c + pcre2-dlopen.h pe-header.h pkcs11-util.c pkcs11-util.h diff --git a/src/journal/pcre2-dlopen.c b/src/shared/pcre2-dlopen.c similarity index 100% rename from src/journal/pcre2-dlopen.c rename to src/shared/pcre2-dlopen.c diff --git a/src/journal/pcre2-dlopen.h b/src/shared/pcre2-dlopen.h similarity index 100% rename from src/journal/pcre2-dlopen.h rename to src/shared/pcre2-dlopen.h diff --git a/src/test/test-dlopen-so.c b/src/test/test-dlopen-so.c index ea2ef31b1fd..002f666ed85 100644 --- a/src/test/test-dlopen-so.c +++ b/src/test/test-dlopen-so.c @@ -5,10 +5,12 @@ #include "bpf-dlopen.h" #include "cryptsetup-util.h" +#include "elf-util.h" #include "idn-util.h" #include "libfido2-util.h" #include "macro.h" #include "main-func.h" +#include "pcre2-dlopen.h" #include "pwquality-util.h" #include "qrcode-util.h" #include "tests.h" @@ -49,6 +51,15 @@ static int run(int argc, char **argv) { assert_se(dlopen_bpf() >= 0); #endif +#if HAVE_ELFUTILS + assert_se(dlopen_dw() >= 0); + assert_se(dlopen_elf() >= 0); +#endif + +#if HAVE_PCRE2 + assert_se(dlopen_pcre2() >= 0); +#endif + return 0; } From a819291fd93da6828557908bcf4cf8b0673bdaae Mon Sep 17 00:00:00 2001 From: Daan De Meyer Date: Tue, 22 Feb 2022 11:06:00 +0000 Subject: [PATCH 08/41] systemctl: Show how long a service ran for after it exited in status output (cherry picked from commit 0802f62efc1d1c67d5be67223b529c93536cf2ed) Related: #2013213 --- src/systemctl/systemctl-show.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/systemctl/systemctl-show.c b/src/systemctl/systemctl-show.c index 37c898f3131..9b23471990b 100644 --- a/src/systemctl/systemctl-show.c +++ b/src/systemctl/systemctl-show.c @@ -433,6 +433,18 @@ static void print_status_info( FORMAT_TIMESTAMP_STYLE(until_timestamp, arg_timestamp_style), FORMAT_TIMESTAMP_RELATIVE(until_timestamp)); } + + if (!endswith(i->id, ".target") && + STRPTR_IN_SET(i->active_state, "inactive", "failed") && + timestamp_is_set(i->active_enter_timestamp) && + timestamp_is_set(i->active_exit_timestamp) && + i->active_exit_timestamp >= i->active_enter_timestamp) { + + usec_t duration; + + duration = i->active_exit_timestamp - i->active_enter_timestamp; + printf(" Duration: %s\n", FORMAT_TIMESPAN(duration, MSEC_PER_SEC)); + } } else printf("\n"); From 822c454dc2267ec93ae238e5351793468f61387b Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Mon, 21 Feb 2022 13:08:20 +0100 Subject: [PATCH 09/41] time-util: introduce TIMESTAMP_UNIX Allow formatting timestamps as number of seconds since the Epoch for easier machine parsing. Fixes: #22567 ``` $ systemctl show systemd-journald | grep Timestamp WatchdogTimestampMonotonic=0 ExecMainStartTimestamp=Sat 2021-12-11 15:25:57 CET ExecMainStartTimestampMonotonic=13030408 ExecMainExitTimestampMonotonic=0 StateChangeTimestamp=Sat 2021-12-11 15:25:57 CET StateChangeTimestampMonotonic=13049273 InactiveExitTimestamp=Sat 2021-12-11 15:25:57 CET InactiveExitTimestampMonotonic=13030430 ActiveEnterTimestamp=Sat 2021-12-11 15:25:57 CET ActiveEnterTimestampMonotonic=13049273 ActiveExitTimestamp=Sat 2021-12-11 15:25:57 CET ActiveExitTimestampMonotonic=12997236 InactiveEnterTimestamp=Sat 2021-12-11 15:25:57 CET InactiveEnterTimestampMonotonic=13028890 ConditionTimestamp=Sat 2021-12-11 15:25:57 CET ConditionTimestampMonotonic=13029539 AssertTimestamp=Sat 2021-12-11 15:25:57 CET AssertTimestampMonotonic=13029540 $ systemctl show --timestamp=unix systemd-journald | grep Timestamp WatchdogTimestampMonotonic=0 ExecMainStartTimestamp=@1639232757 ExecMainStartTimestampMonotonic=13030408 ExecMainExitTimestampMonotonic=0 StateChangeTimestamp=@1639232757 StateChangeTimestampMonotonic=13049273 InactiveExitTimestamp=@1639232757 InactiveExitTimestampMonotonic=13030430 ActiveEnterTimestamp=@1639232757 ActiveEnterTimestampMonotonic=13049273 ActiveExitTimestamp=@1639232757 ActiveExitTimestampMonotonic=12997236 InactiveEnterTimestamp=@1639232757 InactiveEnterTimestampMonotonic=13028890 ConditionTimestamp=@1639232757 ConditionTimestampMonotonic=13029539 AssertTimestamp=@1639232757 AssertTimestampMonotonic=13029540 ``` (cherry picked from commit ed4a5b434517eeebc508379476cf112704e7981c) Related: #2013213 --- src/basic/time-util.c | 11 +++++++++++ src/basic/time-util.h | 1 + src/test/test-time-util.c | 5 +++++ 3 files changed, 17 insertions(+) diff --git a/src/basic/time-util.c b/src/basic/time-util.c index b659d6905d9..c0841af8f3d 100644 --- a/src/basic/time-util.c +++ b/src/basic/time-util.c @@ -320,11 +320,13 @@ char *format_timestamp_style( time_t sec; size_t n; bool utc = false, us = false; + int r; assert(buf); switch (style) { case TIMESTAMP_PRETTY: + case TIMESTAMP_UNIX: break; case TIMESTAMP_US: us = true; @@ -350,6 +352,14 @@ char *format_timestamp_style( if (t <= 0 || t == USEC_INFINITY) return NULL; /* Timestamp is unset */ + if (style == TIMESTAMP_UNIX) { + r = snprintf(buf, l, "@" USEC_FMT, t / USEC_PER_SEC); /* round down µs → s */ + if (r < 0 || (size_t) r >= l) + return NULL; /* Doesn't fit */ + + return buf; + } + /* Let's not format times with years > 9999 */ if (t > USEC_TIMESTAMP_FORMATTABLE_MAX) { assert(l >= STRLEN("--- XXXX-XX-XX XX:XX:XX") + 1); @@ -1632,6 +1642,7 @@ static const char* const timestamp_style_table[_TIMESTAMP_STYLE_MAX] = { [TIMESTAMP_US] = "us", [TIMESTAMP_UTC] = "utc", [TIMESTAMP_US_UTC] = "us+utc", + [TIMESTAMP_UNIX] = "unix", }; /* Use the macro for enum → string to allow for aliases */ diff --git a/src/basic/time-util.h b/src/basic/time-util.h index 895af882998..01a72026e39 100644 --- a/src/basic/time-util.h +++ b/src/basic/time-util.h @@ -34,6 +34,7 @@ typedef enum TimestampStyle { TIMESTAMP_US, TIMESTAMP_UTC, TIMESTAMP_US_UTC, + TIMESTAMP_UNIX, _TIMESTAMP_STYLE_MAX, _TIMESTAMP_STYLE_INVALID = -EINVAL, } TimestampStyle; diff --git a/src/test/test-time-util.c b/src/test/test-time-util.c index 554693834bf..799d271a443 100644 --- a/src/test/test-time-util.c +++ b/src/test/test-time-util.c @@ -325,6 +325,11 @@ TEST(format_timestamp) { assert_se(parse_timestamp(buf, &y) >= 0); assert_se(x / USEC_PER_SEC == y / USEC_PER_SEC); + assert_se(format_timestamp_style(buf, sizeof(buf), x, TIMESTAMP_UNIX)); + log_debug("%s", buf); + assert_se(parse_timestamp(buf, &y) >= 0); + assert_se(x / USEC_PER_SEC == y / USEC_PER_SEC); + assert_se(format_timestamp_style(buf, sizeof(buf), x, TIMESTAMP_UTC)); log_debug("%s", buf); assert_se(parse_timestamp(buf, &y) >= 0); From 654e059428b818558a12263fdb87edaa3517157d Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Mon, 21 Feb 2022 13:14:18 +0100 Subject: [PATCH 10/41] systemctl,man: update docs for `--timestamp=` (cherry picked from commit b58b4a9f379748fec667fb60606de945eaafadbe) Related: #2013213 --- man/systemctl.xml | 7 +++++++ src/systemctl/systemctl.c | 7 ++----- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/man/systemctl.xml b/man/systemctl.xml index 3b3d709ab3f..f28579e05d4 100644 --- a/man/systemctl.xml +++ b/man/systemctl.xml @@ -2305,6 +2305,13 @@ Jan 12 10:46:45 example.com bluetoothd[8900]: gatt-time-server: Input/output err + + + + @seconds-since-the-epoch + + + diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 9031e685ea5..0489796a75c 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -296,11 +296,8 @@ static int systemctl_help(void) { " --boot-loader-entry=NAME\n" " Boot into a specific boot loader entry on next boot\n" " --plain Print unit dependencies as a list instead of a tree\n" - " --timestamp=FORMAT Change format of printed timestamps.\n" - " 'pretty' (default): 'Day YYYY-MM-DD HH:MM:SS TZ\n" - " 'us': 'Day YYYY-MM-DD HH:MM:SS.UUUUUU TZ\n" - " 'utc': 'Day YYYY-MM-DD HH:MM:SS UTC\n" - " 'us+utc': 'Day YYYY-MM-DD HH:MM:SS.UUUUUU UTC\n" + " --timestamp=FORMAT Change format of printed timestamps (pretty, unix,\n" + " us, utc, us+utc)\n" " --read-only Create read-only bind mount\n" " --mkdir Create directory before mounting, if missing\n" " --marked Restart/reload previously marked units\n" From 2dc95f3f63a4f520c4487f233ec2bc2903dbbfe4 Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Fri, 18 Feb 2022 23:09:18 +0100 Subject: [PATCH 11/41] systemctl: make `--timestamp=` affect the `show` verb as well Currently the `--timestamp=` option has no effect on timestamps shown by `systemctl show`, let's fix that. Spotted in #22567. Before: ``` $ systemctl show --timestamp=us+utc systemd-journald | grep Timestamp= ExecMainStartTimestamp=Sat 2021-12-11 15:25:57 CET StateChangeTimestamp=Sat 2021-12-11 15:25:57 CET InactiveExitTimestamp=Sat 2021-12-11 15:25:57 CET ActiveEnterTimestamp=Sat 2021-12-11 15:25:57 CET ActiveExitTimestamp=Sat 2021-12-11 15:25:57 CET InactiveEnterTimestamp=Sat 2021-12-11 15:25:57 CET ConditionTimestamp=Sat 2021-12-11 15:25:57 CET AssertTimestamp=Sat 2021-12-11 15:25:57 CET ``` After: ``` $ systemctl show --timestamp=us+utc systemd-journald | grep Timestamp= ExecMainStartTimestamp=Sat 2021-12-11 14:25:57.177848 UTC StateChangeTimestamp=Sat 2021-12-11 14:25:57.196714 UTC InactiveExitTimestamp=Sat 2021-12-11 14:25:57.177871 UTC ActiveEnterTimestamp=Sat 2021-12-11 14:25:57.196714 UTC ActiveExitTimestamp=Sat 2021-12-11 14:25:57.144677 UTC InactiveEnterTimestamp=Sat 2021-12-11 14:25:57.176331 UTC ConditionTimestamp=Sat 2021-12-11 14:25:57.176980 UTC AssertTimestamp=Sat 2021-12-11 14:25:57.176980 UTC ``` (cherry picked from commit a59e5c625da5a6e0c46e493d55f2f4212e9457ca) Related: #2013213 --- src/systemctl/systemctl-show.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/systemctl/systemctl-show.c b/src/systemctl/systemctl-show.c index 9b23471990b..7a6655da745 100644 --- a/src/systemctl/systemctl-show.c +++ b/src/systemctl/systemctl-show.c @@ -1001,6 +1001,20 @@ static int print_property(const char *name, const char *expected_value, sd_bus_m } break; + case SD_BUS_TYPE_UINT64: + if (endswith(name, "Timestamp")) { + uint64_t timestamp; + + r = sd_bus_message_read_basic(m, bus_type, ×tamp); + if (r < 0) + return r; + + bus_print_property_value(name, expected_value, flags, FORMAT_TIMESTAMP_STYLE(timestamp, arg_timestamp_style)); + + return 1; + } + break; + case SD_BUS_TYPE_STRUCT: if (contents[0] == SD_BUS_TYPE_UINT32 && streq(name, "Job")) { From f4e696c80fa81b41d7f7ddaa7dd4be5985bbe3fc Mon Sep 17 00:00:00 2001 From: Evgeny Vereshchagin Date: Tue, 15 Feb 2022 01:13:10 +0000 Subject: [PATCH 12/41] tests: allow running all the services with SYSTEMD_LOG_LEVEL It should make it easier to figure out what exactly services do there. For example, with SYSTEMD_LOG_LEVEL=debug userdbd (v249) prints ``` varlink-5: New incoming message: {"method":"io.systemd.UserDatabase.GetUserRecord","parameters":{}} ``` before it crashes and systemd-resolved prints ``` varlink-21: New incoming message: {"method":"io.systemd.Resolve.ResolveAddress","parameters":{"address":[127,0,0,1],"flags":0,"ifindex":1000000,"family":0}} ``` and those messages are helpful (especially when scripts causing them aren't clever enough to keep track of random stuff they send to systemd :-)) (cherry picked from commit bf6ef6b6a9156e5f52ee69ce0c529a246f103e54) Related: #2013213 --- test/test-functions | 3 +++ 1 file changed, 3 insertions(+) diff --git a/test/test-functions b/test/test-functions index dcc893733c3..a299f5ff1f5 100644 --- a/test/test-functions +++ b/test/test-functions @@ -1142,6 +1142,9 @@ install_systemd() { # enable debug logging in PID1 echo LogLevel=debug >>"$initdir/etc/systemd/system.conf" + if [[ -n "$TEST_SYSTEMD_LOG_LEVEL" ]]; then + echo DefaultEnvironment=SYSTEMD_LOG_LEVEL="$TEST_SYSTEMD_LOG_LEVEL" >>"$initdir/etc/systemd/system.conf" + fi # store coredumps in journal echo Storage=journal >>"$initdir/etc/systemd/coredump.conf" # Propagate SYSTEMD_UNIT_PATH to user systemd managers From f87bb37597b089d07866822ba891ad701fecbcc3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 8 Feb 2022 11:52:17 +0100 Subject: [PATCH 13/41] coredump: raise the coredump save size on 64bit systems to 32G (and lower it to 1G on 32bit systems) Apparently 2G is too low for various real-life systems. But raising it universally above 2^32 sounds wrong to me, since that makes no sense on 32bit systems, that we still support. Hence, let's raise the limit to 32G on 64bit systems, and *lower* it to 1G on 32bit systems. 32G is 4 orders of magnitude higher then the old settings. Let's hope that's enough for now. Should this not be enough we can raise it further. Fixes: #22076 (cherry picked from commit e677041e7a6988f73de802db6e49d962d432944b) Related: #2013213 --- src/coredump/coredump.c | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/coredump/coredump.c b/src/coredump/coredump.c index 6a6e9765d4a..fd156370b28 100644 --- a/src/coredump/coredump.c +++ b/src/coredump/coredump.c @@ -48,8 +48,14 @@ #include "uid-alloc-range.h" #include "user-util.h" -/* The maximum size up to which we process coredumps */ -#define PROCESS_SIZE_MAX ((uint64_t) (2LLU*1024LLU*1024LLU*1024LLU)) +/* The maximum size up to which we process coredumps. We use 1G on 32bit systems, and 32G on 64bit systems */ +#if __SIZEOF_POINTER__ == 4 +#define PROCESS_SIZE_MAX ((uint64_t) (1LLU*1024LLU*1024LLU*1024LLU)) +#elif __SIZEOF_POINTER__ == 8 +#define PROCESS_SIZE_MAX ((uint64_t) (32LLU*1024LLU*1024LLU*1024LLU)) +#else +#error "Unexpected pointer size" +#endif /* The maximum size up to which we leave the coredump around on disk */ #define EXTERNAL_SIZE_MAX PROCESS_SIZE_MAX From 656e9973e31f5f96afd5e516f36c6b839be02053 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 4 Feb 2022 17:39:44 +0100 Subject: [PATCH 14/41] repart: fix sector size handling This queries the sector size from libfdisk instead of assuming 512, and uses that when converting from bytes to the offset/size values libfdisk expects. This is an alternative to Tom Yan's #21823, but prefers using libfdisk's own ideas of the sector size instead of going directly to the backing device via ioctls. (libfdisk can after all also operate on regular files, where the sector size concept doesn't necessarily apply the same way.) This also makes the "grain" variable, i.e. how we'll align the partitions. Previously this was hardcoded to 4K, and that still will be the minimum grain we use, but should the sector size be larger than that we'll use the next multiple of the sector size instead. (cherry picked from commit 994b303123ebe6a140bf3e56c66aa66119ae7d95) Related: #2013213 --- src/partition/repart.c | 212 +++++++++++++++++++++++++---------------- 1 file changed, 132 insertions(+), 80 deletions(-) diff --git a/src/partition/repart.c b/src/partition/repart.c index d08f47f2c47..0862a37a8dc 100644 --- a/src/partition/repart.c +++ b/src/partition/repart.c @@ -195,6 +195,8 @@ struct Context { uint64_t start, end, total; struct fdisk_context *fdisk_context; + uint64_t sector_size; + uint64_t grain_size; sd_id128_t seed; }; @@ -407,9 +409,12 @@ static bool context_drop_one_priority(Context *context) { return true; } -static uint64_t partition_min_size(const Partition *p) { +static uint64_t partition_min_size(Context *context, const Partition *p) { uint64_t sz; + assert(context); + assert(p); + /* Calculate the disk space we really need at minimum for this partition. If the partition already * exists the current size is what we really need. If it doesn't exist yet refuse to allocate less * than 4K. @@ -428,50 +433,60 @@ static uint64_t partition_min_size(const Partition *p) { uint64_t d = 0; if (p->encrypt != ENCRYPT_OFF) - d += round_up_size(LUKS2_METADATA_SIZE, 4096); + d += round_up_size(LUKS2_METADATA_SIZE, context->grain_size); if (p->copy_blocks_size != UINT64_MAX) - d += round_up_size(p->copy_blocks_size, 4096); + d += round_up_size(p->copy_blocks_size, context->grain_size); else if (p->format || p->encrypt != ENCRYPT_OFF) { uint64_t f; /* If we shall synthesize a file system, take minimal fs size into account (assumed to be 4K if not known) */ - f = p->format ? minimal_size_by_fs_name(p->format) : UINT64_MAX; - d += f == UINT64_MAX ? 4096 : f; + f = p->format ? round_up_size(minimal_size_by_fs_name(p->format), context->grain_size) : UINT64_MAX; + d += f == UINT64_MAX ? context->grain_size : f; } if (d > sz) sz = d; } - return MAX(p->size_min != UINT64_MAX ? p->size_min : DEFAULT_MIN_SIZE, sz); + return MAX(round_up_size(p->size_min != UINT64_MAX ? p->size_min : DEFAULT_MIN_SIZE, context->grain_size), sz); } -static uint64_t partition_max_size(const Partition *p) { +static uint64_t partition_max_size(const Context *context, const Partition *p) { + uint64_t sm; + /* Calculate how large the partition may become at max. This is generally the configured maximum * size, except when it already exists and is larger than that. In that case it's the existing size, * since we never want to shrink partitions. */ + assert(context); + assert(p); + if (PARTITION_IS_FOREIGN(p)) { /* Don't allow changing size of partitions not managed by us */ assert(p->current_size != UINT64_MAX); return p->current_size; } + sm = round_down_size(p->size_max, context->grain_size); + if (p->current_size != UINT64_MAX) - return MAX(p->current_size, p->size_max); + return MAX(p->current_size, sm); - return p->size_max; + return sm; } -static uint64_t partition_min_size_with_padding(const Partition *p) { +static uint64_t partition_min_size_with_padding(Context *context, const Partition *p) { uint64_t sz; /* Calculate the disk space we need for this partition plus any free space coming after it. This * takes user configured padding into account as well as any additional whitespace needed to align * the next partition to 4K again. */ - sz = partition_min_size(p); + assert(context); + assert(p); + + sz = partition_min_size(context, p); if (p->padding_min != UINT64_MAX) sz += p->padding_min; @@ -479,11 +494,11 @@ static uint64_t partition_min_size_with_padding(const Partition *p) { if (PARTITION_EXISTS(p)) { /* If the partition wasn't aligned, add extra space so that any we might add will be aligned */ assert(p->offset != UINT64_MAX); - return round_up_size(p->offset + sz, 4096) - p->offset; + return round_up_size(p->offset + sz, context->grain_size) - p->offset; } /* If this is a new partition we'll place it aligned, hence we just need to round up the required size here */ - return round_up_size(sz, 4096); + return round_up_size(sz, context->grain_size); } static uint64_t free_area_available(const FreeArea *a) { @@ -495,9 +510,12 @@ static uint64_t free_area_available(const FreeArea *a) { return a->size - a->allocated; } -static uint64_t free_area_available_for_new_partitions(const FreeArea *a) { +static uint64_t free_area_available_for_new_partitions(Context *context, const FreeArea *a) { uint64_t avail; + assert(context); + assert(a); + /* Similar to free_area_available(), but takes into account that the required size and padding of the * preceding partition is honoured. */ @@ -505,16 +523,16 @@ static uint64_t free_area_available_for_new_partitions(const FreeArea *a) { if (a->after) { uint64_t need, space_end, new_end; - need = partition_min_size_with_padding(a->after); + need = partition_min_size_with_padding(context, a->after); assert(a->after->offset != UINT64_MAX); assert(a->after->current_size != UINT64_MAX); /* Calculate where the free area ends, based on the offset of the partition preceding it */ - space_end = round_up_size(a->after->offset + a->after->current_size, 4096) + avail; + space_end = round_up_size(a->after->offset + a->after->current_size, context->grain_size) + avail; /* Calculate where the partition would end when we give it as much as it needs */ - new_end = round_up_size(a->after->offset + need, 4096); + new_end = round_up_size(a->after->offset + need, context->grain_size); /* Calculate saturated difference of the two: that's how much we have free for other partitions */ return LESS_BY(space_end, new_end); @@ -523,15 +541,18 @@ static uint64_t free_area_available_for_new_partitions(const FreeArea *a) { return avail; } -static int free_area_compare(FreeArea *const *a, FreeArea *const*b) { - return CMP(free_area_available_for_new_partitions(*a), - free_area_available_for_new_partitions(*b)); +static int free_area_compare(FreeArea *const *a, FreeArea *const*b, Context *context) { + assert(context); + + return CMP(free_area_available_for_new_partitions(context, *a), + free_area_available_for_new_partitions(context, *b)); } -static uint64_t charge_size(uint64_t total, uint64_t amount) { +static uint64_t charge_size(Context *context, uint64_t total, uint64_t amount) { + assert(context); /* Subtract the specified amount from total, rounding up to multiple of 4K if there's room */ assert(amount <= total); - return LESS_BY(total, round_up_size(amount, 4096)); + return LESS_BY(total, round_up_size(amount, context->grain_size)); } static uint64_t charge_weight(uint64_t total, uint64_t amount) { @@ -545,14 +566,14 @@ static bool context_allocate_partitions(Context *context, uint64_t *ret_largest_ assert(context); /* Sort free areas by size, putting smallest first */ - typesafe_qsort(context->free_areas, context->n_free_areas, free_area_compare); + typesafe_qsort_r(context->free_areas, context->n_free_areas, free_area_compare, context); /* In any case return size of the largest free area (i.e. not the size of all free areas * combined!) */ if (ret_largest_free_area) *ret_largest_free_area = context->n_free_areas == 0 ? 0 : - free_area_available_for_new_partitions(context->free_areas[context->n_free_areas-1]); + free_area_available_for_new_partitions(context, context->free_areas[context->n_free_areas-1]); /* A simple first-fit algorithm. We return true if we can fit the partitions in, otherwise false. */ LIST_FOREACH(partitions, p, context->partitions) { @@ -565,13 +586,13 @@ static bool context_allocate_partitions(Context *context, uint64_t *ret_largest_ continue; /* How much do we need to fit? */ - required = partition_min_size_with_padding(p); - assert(required % 4096 == 0); + required = partition_min_size_with_padding(context, p); + assert(required % context->grain_size == 0); for (size_t i = 0; i < context->n_free_areas; i++) { a = context->free_areas[i]; - if (free_area_available_for_new_partitions(a) >= required) { + if (free_area_available_for_new_partitions(context, a) >= required) { fits = true; break; } @@ -683,8 +704,8 @@ static int context_grow_partitions_phase( if (r < 0) return r; - rsz = partition_min_size(p); - xsz = partition_max_size(p); + rsz = partition_min_size(context, p); + xsz = partition_max_size(context, p); if (phase == PHASE_OVERCHARGE && rsz > share) { /* This partition needs more than its calculated share. Let's assign @@ -712,13 +733,13 @@ static int context_grow_partitions_phase( /* Never change of foreign partitions (i.e. those we don't manage) */ p->new_size = p->current_size; else - p->new_size = MAX(round_down_size(share, 4096), rsz); + p->new_size = MAX(round_down_size(share, context->grain_size), rsz); charge = true; } if (charge) { - *span = charge_size(*span, p->new_size); + *span = charge_size(context, *span, p->new_size); *weight_sum = charge_weight(*weight_sum, p->weight); } @@ -742,7 +763,7 @@ static int context_grow_partitions_phase( charge = try_again = true; } else if (phase == PHASE_DISTRIBUTE) { - p->new_padding = round_down_size(share, 4096); + p->new_padding = round_down_size(share, context->grain_size); if (p->padding_min != UINT64_MAX && p->new_padding < p->padding_min) p->new_padding = p->padding_min; @@ -750,7 +771,7 @@ static int context_grow_partitions_phase( } if (charge) { - *span = charge_size(*span, p->new_padding); + *span = charge_size(context, *span, p->new_padding); *weight_sum = charge_weight(*weight_sum, p->padding_weight); } @@ -779,7 +800,7 @@ static int context_grow_partitions_on_free_area(Context *context, FreeArea *a) { assert(a->after->offset != UINT64_MAX); assert(a->after->current_size != UINT64_MAX); - span += round_up_size(a->after->offset + a->after->current_size, 4096) - a->after->offset; + span += round_up_size(a->after->offset + a->after->current_size, context->grain_size) - a->after->offset; } for (GrowPartitionPhase phase = 0; phase < _GROW_PARTITION_PHASE_MAX;) { @@ -799,13 +820,13 @@ static int context_grow_partitions_on_free_area(Context *context, FreeArea *a) { assert(a->after->new_size != UINT64_MAX); /* Calculate new size and align (but ensure this doesn't shrink the size) */ - m = MAX(a->after->new_size, round_down_size(a->after->new_size + span, 4096)); + m = MAX(a->after->new_size, round_down_size(a->after->new_size + span, context->grain_size)); - xsz = partition_max_size(a->after); + xsz = partition_max_size(context, a->after); if (xsz != UINT64_MAX && m > xsz) m = xsz; - span = charge_size(span, m - a->after->new_size); + span = charge_size(context, span, m - a->after->new_size); a->after->new_size = m; } @@ -824,13 +845,13 @@ static int context_grow_partitions_on_free_area(Context *context, FreeArea *a) { continue; assert(p->new_size != UINT64_MAX); - m = MAX(p->new_size, round_down_size(p->new_size + span, 4096)); + m = MAX(p->new_size, round_down_size(p->new_size + span, context->grain_size)); - xsz = partition_max_size(p); + xsz = partition_max_size(context, p); if (xsz != UINT64_MAX && m > xsz) m = xsz; - span = charge_size(span, m - p->new_size); + span = charge_size(context, span, m - p->new_size); p->new_size = m; if (span == 0) @@ -910,7 +931,7 @@ static void context_place_partitions(Context *context) { } else start = context->start; - start = round_up_size(start, 4096); + start = round_up_size(start, context->grain_size); left = a->size; LIST_FOREACH(partitions, p, context->partitions) { @@ -1422,6 +1443,8 @@ static int determine_current_padding( struct fdisk_context *c, struct fdisk_table *t, struct fdisk_partition *p, + uint64_t secsz, + uint64_t grainsz, uint64_t *ret) { size_t n_partitions; @@ -1435,8 +1458,8 @@ static int determine_current_padding( return log_error_errno(SYNTHETIC_ERRNO(EIO), "Partition has no end!"); offset = fdisk_partition_get_end(p); - assert(offset < UINT64_MAX / 512); - offset *= 512; + assert(offset < UINT64_MAX / secsz); + offset *= secsz; n_partitions = fdisk_table_get_nents(t); for (size_t i = 0; i < n_partitions; i++) { @@ -1454,8 +1477,8 @@ static int determine_current_padding( continue; start = fdisk_partition_get_start(q); - assert(start < UINT64_MAX / 512); - start *= 512; + assert(start < UINT64_MAX / secsz); + start *= secsz; if (start >= offset && (next == UINT64_MAX || next > start)) next = start; @@ -1467,16 +1490,16 @@ static int determine_current_padding( assert(next < UINT64_MAX); next++; /* The last LBA is one sector before the end */ - assert(next < UINT64_MAX / 512); - next *= 512; + assert(next < UINT64_MAX / secsz); + next *= secsz; if (offset > next) return log_error_errno(SYNTHETIC_ERRNO(EIO), "Partition end beyond disk end."); } assert(next >= offset); - offset = round_up_size(offset, 4096); - next = round_down_size(next, 4096); + offset = round_up_size(offset, grainsz); + next = round_down_size(next, grainsz); *ret = LESS_BY(next, offset); /* Saturated subtraction, rounding might have fucked things up */ return 0; @@ -1549,6 +1572,8 @@ static int context_load_partition_table( bool from_scratch = false; sd_id128_t disk_uuid; size_t n_partitions; + unsigned long secsz; + uint64_t grainsz; int r; assert(context); @@ -1583,8 +1608,12 @@ static int context_load_partition_table( if (r < 0) return log_error_errno(errno, "Failed to stat block device '%s': %m", node); - if (S_ISREG(st.st_mode) && st.st_size == 0) + if (S_ISREG(st.st_mode) && st.st_size == 0) { + /* User the fallback values if we have no better idea */ + context->sector_size = 512; + context->grain_size = 4096; return /* from_scratch = */ true; + } r = -EINVAL; } @@ -1602,6 +1631,23 @@ static int context_load_partition_table( if (flock(fdisk_get_devfd(c), arg_dry_run ? LOCK_SH : LOCK_EX) < 0) return log_error_errno(errno, "Failed to lock block device: %m"); + /* The offsets/sizes libfdisk returns to us will be in multiple of the sector size of the + * device. This is typically 512, and sometimes 4096. Let's query libfdisk once for it, and then use + * it for all our needs. Note that the values we use ourselves always are in bytes though, thus mean + * the same thing universally. Also note that regardless what kind of sector size is in use we'll + * place partitions at multiples of 4K. */ + secsz = fdisk_get_sector_size(c); + + /* Insist on a power of two, and that it's a multiple of 512, i.e. the traditional sector size. */ + if (secsz < 512 || secsz != 1UL << log2u64(secsz)) + return log_error_errno(errno, "Sector size %lu is not a power of two larger than 512? Refusing.", secsz); + + /* Use at least 4K, and ensure it's a multiple of the sector size, regardless if that is smaller or + * larger */ + grainsz = secsz < 4096 ? 4096 : secsz; + + log_debug("Sector size of device is %lu bytes. Using grain size of %" PRIu64 ".", secsz, grainsz); + switch (arg_empty) { case EMPTY_REFUSE: @@ -1732,12 +1778,12 @@ static int context_load_partition_table( } sz = fdisk_partition_get_size(p); - assert_se(sz <= UINT64_MAX/512); - sz *= 512; + assert_se(sz <= UINT64_MAX/secsz); + sz *= secsz; start = fdisk_partition_get_start(p); - assert_se(start <= UINT64_MAX/512); - start *= 512; + assert_se(start <= UINT64_MAX/secsz); + start *= secsz; partno = fdisk_partition_get_partno(p); @@ -1762,7 +1808,7 @@ static int context_load_partition_table( pp->current_partition = p; fdisk_ref_partition(p); - r = determine_current_padding(c, t, p, &pp->current_padding); + r = determine_current_padding(c, t, p, secsz, grainsz, &pp->current_padding); if (r < 0) return r; @@ -1795,7 +1841,7 @@ static int context_load_partition_table( np->current_partition = p; fdisk_ref_partition(p); - r = determine_current_padding(c, t, p, &np->current_padding); + r = determine_current_padding(c, t, p, secsz, grainsz, &np->current_padding); if (r < 0) return r; @@ -1812,26 +1858,26 @@ static int context_load_partition_table( add_initial_free_area: nsectors = fdisk_get_nsectors(c); - assert(nsectors <= UINT64_MAX/512); - nsectors *= 512; + assert(nsectors <= UINT64_MAX/secsz); + nsectors *= secsz; first_lba = fdisk_get_first_lba(c); - assert(first_lba <= UINT64_MAX/512); - first_lba *= 512; + assert(first_lba <= UINT64_MAX/secsz); + first_lba *= secsz; last_lba = fdisk_get_last_lba(c); assert(last_lba < UINT64_MAX); last_lba++; - assert(last_lba <= UINT64_MAX/512); - last_lba *= 512; + assert(last_lba <= UINT64_MAX/secsz); + last_lba *= secsz; assert(last_lba >= first_lba); if (left_boundary == UINT64_MAX) { /* No partitions at all? Then the whole disk is up for grabs. */ - first_lba = round_up_size(first_lba, 4096); - last_lba = round_down_size(last_lba, 4096); + first_lba = round_up_size(first_lba, grainsz); + last_lba = round_down_size(last_lba, grainsz); if (last_lba > first_lba) { r = context_add_free_area(context, last_lba - first_lba, NULL); @@ -1842,9 +1888,9 @@ static int context_load_partition_table( /* Add space left of first partition */ assert(left_boundary >= first_lba); - first_lba = round_up_size(first_lba, 4096); - left_boundary = round_down_size(left_boundary, 4096); - last_lba = round_down_size(last_lba, 4096); + first_lba = round_up_size(first_lba, grainsz); + left_boundary = round_down_size(left_boundary, grainsz); + last_lba = round_down_size(last_lba, grainsz); if (left_boundary > first_lba) { r = context_add_free_area(context, left_boundary - first_lba, NULL); @@ -1856,6 +1902,8 @@ static int context_load_partition_table( context->start = first_lba; context->end = last_lba; context->total = nsectors; + context->sector_size = secsz; + context->grain_size = grainsz; context->fdisk_context = TAKE_PTR(c); return from_scratch; @@ -2360,7 +2408,7 @@ static int context_discard_range( if (S_ISBLK(st.st_mode)) { uint64_t range[2], end; - range[0] = round_up_size(offset, 512); + range[0] = round_up_size(offset, context->sector_size); if (offset > UINT64_MAX - size) return -ERANGE; @@ -2369,7 +2417,7 @@ static int context_discard_range( if (end <= range[0]) return 0; - range[1] = round_down_size(end - range[0], 512); + range[1] = round_down_size(end - range[0], context->sector_size); if (range[1] <= 0) return 0; @@ -2519,6 +2567,7 @@ static int context_wipe_and_discard(Context *context, bool from_scratch) { } static int partition_encrypt( + Context *context, Partition *p, const char *node, struct crypt_device **ret_cd, @@ -2532,6 +2581,7 @@ static int partition_encrypt( sd_id128_t uuid; int r; + assert(context); assert(p); assert(p->encrypt != ENCRYPT_OFF); @@ -2579,7 +2629,7 @@ static int partition_encrypt( volume_key_size, &(struct crypt_params_luks2) { .label = strempty(p->new_label), - .sector_size = 512U, + .sector_size = context->sector_size, }); if (r < 0) return log_error_errno(r, "Failed to LUKS2 format future partition: %m"); @@ -2735,7 +2785,7 @@ static int context_copy_blocks(Context *context) { if (r < 0) return log_error_errno(r, "Failed to lock loopback device: %m"); - r = partition_encrypt(p, d->node, &cd, &encrypted, &encrypted_dev_fd); + r = partition_encrypt(context, p, d->node, &cd, &encrypted, &encrypted_dev_fd); if (r < 0) return log_error_errno(r, "Failed to encrypt device: %m"); @@ -2988,7 +3038,7 @@ static int context_mkfs(Context *context) { return log_error_errno(r, "Failed to lock loopback device: %m"); if (p->encrypt != ENCRYPT_OFF) { - r = partition_encrypt(p, d->node, &cd, &encrypted, &encrypted_dev_fd); + r = partition_encrypt(context, p, d->node, &cd, &encrypted, &encrypted_dev_fd); if (r < 0) return log_error_errno(r, "Failed to encrypt device: %m"); @@ -3307,13 +3357,13 @@ static int context_mangle_partitions(Context *context) { if (p->new_size != p->current_size) { assert(p->new_size >= p->current_size); - assert(p->new_size % 512 == 0); + assert(p->new_size % context->sector_size == 0); r = fdisk_partition_size_explicit(p->current_partition, true); if (r < 0) return log_error_errno(r, "Failed to enable explicit sizing: %m"); - r = fdisk_partition_set_size(p->current_partition, p->new_size / 512); + r = fdisk_partition_set_size(p->current_partition, p->new_size / context->sector_size); if (r < 0) return log_error_errno(r, "Failed to grow partition: %m"); @@ -3353,8 +3403,8 @@ static int context_mangle_partitions(Context *context) { _cleanup_(fdisk_unref_parttypep) struct fdisk_parttype *t = NULL; assert(!p->new_partition); - assert(p->offset % 512 == 0); - assert(p->new_size % 512 == 0); + assert(p->offset % context->sector_size == 0); + assert(p->new_size % context->sector_size == 0); assert(!sd_id128_is_null(p->new_uuid)); assert(p->new_label); @@ -3378,11 +3428,11 @@ static int context_mangle_partitions(Context *context) { if (r < 0) return log_error_errno(r, "Failed to enable explicit sizing: %m"); - r = fdisk_partition_set_start(q, p->offset / 512); + r = fdisk_partition_set_start(q, p->offset / context->sector_size); if (r < 0) return log_error_errno(r, "Failed to position partition: %m"); - r = fdisk_partition_set_size(q, p->new_size / 512); + r = fdisk_partition_set_size(q, p->new_size / context->sector_size); if (r < 0) return log_error_errno(r, "Failed to grow partition: %m"); @@ -4746,18 +4796,20 @@ static int resize_backing_fd( } static int determine_auto_size(Context *c) { - uint64_t sum = round_up_size(GPT_METADATA_SIZE, 4096); + uint64_t sum; Partition *p; assert_se(c); + sum = round_up_size(GPT_METADATA_SIZE, 4096); + LIST_FOREACH(partitions, p, c->partitions) { uint64_t m; if (p->dropped) continue; - m = partition_min_size_with_padding(p); + m = partition_min_size_with_padding(c, p); if (m > UINT64_MAX - sum) return log_error_errno(SYNTHETIC_ERRNO(EOVERFLOW), "Image would grow too large, refusing."); From 56f5f917f6ec99ccce5e24b61317572a991f38a6 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 2 Feb 2022 14:20:48 +0900 Subject: [PATCH 15/41] mkdir: allow to create directory whose path contains symlink Fixes a regression caused by 3008a6f21c1c42efe852d69798a2fdd63fe657ec. Before the commit, when `mkdir_parents_internal()` is called from `mkdir_p()`, it uses `_mkdir()` as `flag` is zero. But after the commit, `mkdir_safe_internal()` is always used. Hence, if the path contains a symlink, it fails with -ENOTDIR. To fix the issue, this makes `mkdir_p()` calls `mkdir_parents_internal()` with MKDIR_FOLLOW_SYMLINK flag. Fixes #22334. (cherry picked from commit 5117059ee9f84ed2fd37801ec0b90473db475422) Related: #2013213 --- src/basic/mkdir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/basic/mkdir.c b/src/basic/mkdir.c index 6e2b94d024e..88782ab0d4a 100644 --- a/src/basic/mkdir.c +++ b/src/basic/mkdir.c @@ -162,7 +162,7 @@ int mkdir_p_internal(const char *prefix, const char *path, mode_t mode, uid_t ui assert(_mkdirat != mkdirat); - r = mkdir_parents_internal(prefix, path, mode, uid, gid, flags, _mkdirat); + r = mkdir_parents_internal(prefix, path, mode, uid, gid, flags | MKDIR_FOLLOW_SYMLINK, _mkdirat); if (r < 0) return r; From e2642336046398cb7294c6967978b51865ce6f23 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 2 Feb 2022 15:06:27 +0900 Subject: [PATCH 16/41] mkdir: CHASE_NONEXISTENT cannot used in chase_symlinks_and_stat() (cherry picked from commit e22916e61d1fdb7b46918b605ebf783d9017f9d8) Related: #2013213 --- src/basic/mkdir.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/basic/mkdir.c b/src/basic/mkdir.c index 88782ab0d4a..51a0d74e875 100644 --- a/src/basic/mkdir.c +++ b/src/basic/mkdir.c @@ -42,7 +42,7 @@ int mkdir_safe_internal( if ((flags & MKDIR_FOLLOW_SYMLINK) && S_ISLNK(st.st_mode)) { _cleanup_free_ char *p = NULL; - r = chase_symlinks_and_stat(path, NULL, CHASE_NONEXISTENT, &p, &st, NULL); + r = chase_symlinks_and_stat(path, NULL, 0, &p, &st, NULL); if (r < 0) return r; if (r == 0) From f9ee2182e5c6451c29f8156cb3ec946bf68f1cb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 23 Dec 2021 12:55:40 +0100 Subject: [PATCH 17/41] meson: move efi file lists closer to where they are used The goal is to have the detection of features and paths done first, and then the build target constructions second. (cherry picked from commit 65dcf9f9a0d877de0dc53558547462a7f1750c78) Related: #2013213 --- src/boot/efi/meson.build | 104 +++++++++++++++++++-------------------- 1 file changed, 51 insertions(+), 53 deletions(-) diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build index e10e51cf4e3..1125c64ea3c 100644 --- a/src/boot/efi/meson.build +++ b/src/boot/efi/meson.build @@ -99,59 +99,6 @@ if efi_lds == '' subdir_done() endif -efi_headers = files(''' - bcd.h - console.h - cpio.h - devicetree.h - disk.h - drivers.h - graphics.h - linux.h - measure.h - missing_efi.h - pe.h - random-seed.h - shim.h - splash.h - util.h - xbootldr.h -'''.split()) - -common_sources = ''' - assert.c - devicetree.c - disk.c - graphics.c - measure.c - pe.c - secure-boot.c - util.c -'''.split() - -systemd_boot_sources = ''' - bcd.c - boot.c - console.c - drivers.c - random-seed.c - shim.c - xbootldr.c -'''.split() - -stub_sources = ''' - cpio.c - initrd.c - splash.c - stub.c -'''.split() - -if efi_arch[1] in ['ia32', 'x86_64'] - stub_sources += 'linux_x86.c' -else - stub_sources += 'linux.c' -endif - conf.set10('HAVE_GNU_EFI', true) conf.set_quoted('EFI_MACHINE_TYPE_NAME', efi_arch[0]) @@ -332,6 +279,57 @@ if efi_cc_version.contains('clang') and efi_cc_version.split('.')[0].split(' ')[ efi_ldflags += ['-Wl,-T,' + efi_lds, '-Wno-unused-command-line-argument'] endif +############################################################ + +efi_headers = files( + 'bcd.h', + 'console.h', + 'cpio.h', + 'devicetree.h', + 'disk.h', + 'drivers.h', + 'graphics.h', + 'linux.h', + 'measure.h', + 'missing_efi.h', + 'pe.h', + 'random-seed.h', + 'shim.h', + 'splash.h', + 'util.h', + 'xbootldr.h') + +common_sources = [ + 'assert.c', + 'devicetree.c', + 'disk.c', + 'graphics.c', + 'measure.c', + 'pe.c', + 'secure-boot.c', + 'util.c'] + +systemd_boot_sources = [ + 'bcd.c', + 'boot.c', + 'console.c', + 'drivers.c', + 'random-seed.c', + 'shim.c', + 'xbootldr.c'] + +stub_sources = [ + 'cpio.c', + 'initrd.c', + 'splash.c', + 'stub.c'] + +if efi_arch[1] in ['ia32', 'x86_64'] + stub_sources += 'linux_x86.c' +else + stub_sources += 'linux.c' +endif + systemd_boot_objects = [] stub_objects = [] foreach file : fundamental_source_paths + common_sources + systemd_boot_sources + stub_sources From 8851b963a239aa59946922dfbb088193d2e7013a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 23 Dec 2021 13:05:01 +0100 Subject: [PATCH 18/41] meson: move efi summary() section to src/boot/efi This way we can add the entries more naturally in the same place where they are defined. (cherry picked from commit 3f871f120520aa2d11218735b0741bacc0309b4d) Related: #2013213 --- meson.build | 16 ++++------------ src/boot/efi/meson.build | 9 +++++++++ 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/meson.build b/meson.build index e07875a0543..f040eeab99c 100644 --- a/meson.build +++ b/meson.build @@ -43,6 +43,10 @@ endif skip_deps = want_ossfuzz or want_libfuzzer fuzzer_build = want_ossfuzz or want_libfuzzer +# Create a title-less summary section early, so it ends up first in the output. +# More items are added later after they have been detected. +summary({'build mode' : get_option('mode')}) + ##################################################################### # Try to install the git pre-commit hook @@ -3902,7 +3906,6 @@ alt_time_epoch = run_command('date', '-Is', '-u', '-d', '@@0@'.format(time_epoch check : true).stdout().strip() summary({ - 'build mode' : get_option('mode'), 'split /usr' : split_usr, 'split bin-sbin' : split_bin, 'prefix directory' : prefixdir, @@ -3960,17 +3963,6 @@ summary({ # CPPFLAGS: ${OUR_CPPFLAGS} ${CPPFLAGS} # LDFLAGS: ${OUR_LDFLAGS} ${LDFLAGS} -if conf.get('ENABLE_EFI') == 1 and conf.get('HAVE_GNU_EFI') == 1 - summary({ - 'EFI machine type' : efi_arch[0], - 'EFI CC' : '@0@'.format(' '.join(efi_cc)), - 'EFI LD' : efi_ld, - 'EFI lds' : efi_lds, - 'EFI crt0' : efi_crt0, - 'EFI include directory' : efi_incdir}, - section : 'Extensible Firmware Interface') -endif - found = [] missing = [] diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build index 1125c64ea3c..dd318079fc2 100644 --- a/src/boot/efi/meson.build +++ b/src/boot/efi/meson.build @@ -279,6 +279,15 @@ if efi_cc_version.contains('clang') and efi_cc_version.split('.')[0].split(' ')[ efi_ldflags += ['-Wl,-T,' + efi_lds, '-Wno-unused-command-line-argument'] endif +summary({ + 'EFI machine type' : efi_arch[0], + 'EFI CC' : '@0@'.format(' '.join(efi_cc)), + 'EFI LD' : efi_ld, + 'EFI lds' : efi_lds, + 'EFI crt0' : efi_crt0, + 'EFI include directory' : efi_incdir}, + section : 'Extensible Firmware Interface') + ############################################################ efi_headers = files( From 8ca6af3955e4534ea1aecdb08cf27c0b912b538d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 23 Dec 2021 13:19:42 +0100 Subject: [PATCH 19/41] meson: report SBAT settings (cherry picked from commit e4e44a0107645891e82a538100a7590eb59a516c) Related: #2013213 --- src/boot/efi/meson.build | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build index dd318079fc2..e6280685966 100644 --- a/src/boot/efi/meson.build +++ b/src/boot/efi/meson.build @@ -130,7 +130,6 @@ elif get_option('sbat-distro') != '' if (value == '' or value == 'auto') and not meson.is_cross_build() cmd = 'if [ -e /etc/os-release ]; then . /etc/os-release; else . /usr/lib/os-release; fi; echo $@0@'.format(sbatvar[1]) value = run_command(sh, '-c', cmd).stdout().strip() - message('@0@ (from @1@): @2@'.format(sbatvar[0], sbatvar[1], value)) endif if value == '' error('Required @0@ option not set and autodetection failed'.format(sbatvar[0])) @@ -147,8 +146,11 @@ elif get_option('sbat-distro') != '' pkgver = get_option('sbat-distro-version') if pkgver == '' efi_conf.set('SBAT_DISTRO_VERSION', 'GIT_VERSION') + # This is determined during build, not configuration, so we can't display it yet. + sbat_distro_version_display = '(git version)' else efi_conf.set_quoted('SBAT_DISTRO_VERSION', pkgver) + sbat_distro_version_display = pkgver endif endif @@ -288,6 +290,16 @@ summary({ 'EFI include directory' : efi_incdir}, section : 'Extensible Firmware Interface') +if efi_conf.get('SBAT_DISTRO', '') != '' + summary({ + 'SBAT distro': efi_conf.get('SBAT_DISTRO'), + 'SBAT distro generation': efi_conf.get('SBAT_DISTRO_GENERATION'), + 'SBAT distro version': sbat_distro_version_display, + 'SBAT distro summary': efi_conf.get('SBAT_DISTRO_SUMMARY'), + 'SBAT distro URL': efi_conf.get('SBAT_DISTRO_URL')}, + section : 'Extensible Firmware Interface') +endif + ############################################################ efi_headers = files( From 691000233c70e2366b4d4dd0a8e67880636d0fd0 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Tue, 28 Dec 2021 13:10:39 +0100 Subject: [PATCH 20/41] boot: Build BCD parser only on arches supported by Windows (cherry picked from commit 77fcf28cb88b302453b4c991a6571cb37f10634d) Related: #2013213 --- src/boot/efi/boot.c | 2 ++ src/boot/efi/meson.build | 21 ++++++++++++--------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/boot/efi/boot.c b/src/boot/efi/boot.c index 0286914b8be..83358406f25 100644 --- a/src/boot/efi/boot.c +++ b/src/boot/efi/boot.c @@ -1941,6 +1941,7 @@ static void config_entry_add_osx(Config *config) { } static void config_entry_add_windows(Config *config, EFI_HANDLE *device, EFI_FILE *root_dir) { +#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) _cleanup_freepool_ CHAR8 *bcd = NULL; CHAR16 *title = NULL; EFI_STATUS err; @@ -1961,6 +1962,7 @@ static void config_entry_add_windows(Config *config, EFI_HANDLE *device, EFI_FIL config_entry_add_loader_auto(config, device, root_dir, NULL, L"auto-windows", 'w', title ?: L"Windows Boot Manager", L"\\EFI\\Microsoft\\Boot\\bootmgfw.efi"); +#endif } static void config_entry_add_linux( diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build index e6280685966..6a0c8da9bab 100644 --- a/src/boot/efi/meson.build +++ b/src/boot/efi/meson.build @@ -331,7 +331,6 @@ common_sources = [ 'util.c'] systemd_boot_sources = [ - 'bcd.c', 'boot.c', 'console.c', 'drivers.c', @@ -351,6 +350,18 @@ else stub_sources += 'linux.c' endif +# BCD parser only makes sense on arches that Windows supports. +if efi_arch[1] in ['ia32', 'x86_64', 'arm', 'aarch64'] + systemd_boot_sources += 'bcd.c' + tests += [ + [['src/boot/efi/test-bcd.c'], + [], + [libzstd], + [], + 'HAVE_ZSTD'], + ] +endif + systemd_boot_objects = [] stub_objects = [] foreach file : fundamental_source_paths + common_sources + systemd_boot_sources + stub_sources @@ -408,14 +419,6 @@ endforeach ############################################################ -tests += [ - [['src/boot/efi/test-bcd.c'], - [], - [libzstd], - [], - 'HAVE_ZSTD'], -] - test_efi_disk_img = custom_target( 'test-efi-disk.img', input : [efi_stubs[0][0], efi_stubs[1][1]], From b829ce8e5d413a0e632413e590e633c792c89af7 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Wed, 29 Dec 2021 15:02:04 +0100 Subject: [PATCH 21/41] meson: Remove efi-cc option Changing the efi compiler this way doesn't really work. The gnu-efi header checks as well as supported compiler flag checks use the regular cc that meson detects. Changing the compiler this way will end up with bad compiler flags. For the very same reason, this does not work with a cross-compiler without going through proper meson cross-compilation steps either. The proper way to build systemd-boot with a different compiler is to use a different build folder and then just use the proper ninja build target to only build the bootloader/stub. (cherry picked from commit 52adf0e91ef00d21a2e83f7669d0823667ce6b6c) Related: #2013213 --- meson_options.txt | 2 -- src/boot/efi/meson.build | 14 ++++---------- 2 files changed, 4 insertions(+), 12 deletions(-) diff --git a/meson_options.txt b/meson_options.txt index 401f0933d73..62cdeb42019 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -414,8 +414,6 @@ option('dbus', type : 'combo', choices : ['auto', 'true', 'false'], option('gnu-efi', type : 'combo', choices : ['auto', 'true', 'false'], description : 'gnu-efi support for sd-boot') -option('efi-cc', type : 'array', - description : 'the compiler to use for EFI modules') # Note that LLD does not support PE/COFF relocations # https://lists.llvm.org/pipermail/llvm-dev/2021-March/149234.html option('efi-ld', type : 'combo', choices : ['auto', 'bfd', 'gold'], diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build index 6a0c8da9bab..11e6bf2dd0d 100644 --- a/src/boot/efi/meson.build +++ b/src/boot/efi/meson.build @@ -44,10 +44,6 @@ if not cc.has_header_symbol('efi.h', 'EFI_IMAGE_MACHINE_X64', endif objcopy = find_program('objcopy') -efi_cc = get_option('efi-cc') -if efi_cc.length() == 0 - efi_cc = cc.cmd_array() -endif efi_ld = get_option('efi-ld') if efi_ld == 'auto' @@ -62,7 +58,7 @@ efi_libdir = '' foreach dir : [get_option('efi-libdir'), '/usr/lib/gnuefi' / efi_arch[0], run_command('realpath', '-e', - '/usr/lib' / run_command(efi_cc, '-print-multi-os-directory').stdout().strip()).stdout().strip()] + '/usr/lib' / run_command(cc.cmd_array(), '-print-multi-os-directory').stdout().strip()).stdout().strip()] if dir != '' and fs.is_dir(dir) efi_libdir = dir break @@ -275,15 +271,13 @@ if run_command('grep', '-q', '__CTOR_LIST__', efi_lds).returncode() == 0 ] endif -efi_cc_version = run_command(efi_cc, '--version').stdout().split('\n')[0] -if efi_cc_version.contains('clang') and efi_cc_version.split('.')[0].split(' ')[-1].to_int() <= 10 +if cc.get_id() == 'clang' and cc.version().split('.')[0].to_int() <= 10 # clang <= 10 doesn't pass -T to the linker and then even complains about it being unused efi_ldflags += ['-Wl,-T,' + efi_lds, '-Wno-unused-command-line-argument'] endif summary({ 'EFI machine type' : efi_arch[0], - 'EFI CC' : '@0@'.format(' '.join(efi_cc)), 'EFI LD' : efi_ld, 'EFI lds' : efi_lds, 'EFI crt0' : efi_crt0, @@ -368,7 +362,7 @@ foreach file : fundamental_source_paths + common_sources + systemd_boot_sources o_file = custom_target(file.split('/')[-1] + '.o', input : file, output : file.split('/')[-1] + '.o', - command : [efi_cc, '-c', '@INPUT@', '-o', '@OUTPUT@', efi_cflags], + command : [cc.cmd_array(), '-c', '@INPUT@', '-o', '@OUTPUT@', efi_cflags], depend_files : efi_headers + fundamental_headers) if (fundamental_source_paths + common_sources + systemd_boot_sources).contains(file) systemd_boot_objects += o_file @@ -389,7 +383,7 @@ foreach tuple : [['systemd_boot.so', systemd_boot_efi_name, systemd_boot_objects tuple[0], input : tuple[2], output : tuple[0], - command : [efi_cc, '-o', '@OUTPUT@', efi_ldflags, efi_cflags, tuple[2], '-lefi', '-lgnuefi', '-lgcc'], + command : [cc.cmd_array(), '-o', '@OUTPUT@', efi_ldflags, efi_cflags, tuple[2], '-lefi', '-lgnuefi', '-lgcc'], install : tuple[3], install_dir : bootlibdir) From 0dd5009e275b05970e1efcf633b2a2732849266e Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Wed, 29 Dec 2021 15:13:35 +0100 Subject: [PATCH 22/41] meson: Get objcopy location from compiler (cherry picked from commit 2f2b07226751827303a88f3a301f2d834f3fb97b) Related: #2013213 --- src/boot/efi/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build index 11e6bf2dd0d..144fbb0f432 100644 --- a/src/boot/efi/meson.build +++ b/src/boot/efi/meson.build @@ -43,7 +43,7 @@ if not cc.has_header_symbol('efi.h', 'EFI_IMAGE_MACHINE_X64', subdir_done() endif -objcopy = find_program('objcopy') +objcopy = run_command(cc.cmd_array(), '-print-prog-name=objcopy', check: true).stdout().strip() efi_ld = get_option('efi-ld') if efi_ld == 'auto' From 2a189b071417c3f3c2e0675acc8321addf0a7e15 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Fri, 7 Jan 2022 21:55:50 +0100 Subject: [PATCH 23/41] meson: Use files() for source lists for boot and fundamental This fixes build reproducibility as otherwise the full path of the source files ends up in the output binary. (cherry picked from commit b3c5a7074cd434bc02c4b560afe933d3df24759e) Related: #2013213 --- src/boot/efi/meson.build | 29 +++++++++++++++++------------ src/fundamental/meson.build | 22 +++++++++------------- 2 files changed, 26 insertions(+), 25 deletions(-) diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build index 144fbb0f432..4cc43dc00ce 100644 --- a/src/boot/efi/meson.build +++ b/src/boot/efi/meson.build @@ -312,9 +312,10 @@ efi_headers = files( 'shim.h', 'splash.h', 'util.h', - 'xbootldr.h') + 'xbootldr.h', +) -common_sources = [ +common_sources = files( 'assert.c', 'devicetree.c', 'disk.c', @@ -322,31 +323,34 @@ common_sources = [ 'measure.c', 'pe.c', 'secure-boot.c', - 'util.c'] + 'util.c', +) -systemd_boot_sources = [ +systemd_boot_sources = files( 'boot.c', 'console.c', 'drivers.c', 'random-seed.c', 'shim.c', - 'xbootldr.c'] + 'xbootldr.c', +) -stub_sources = [ +stub_sources = files( 'cpio.c', 'initrd.c', 'splash.c', - 'stub.c'] + 'stub.c', +) if efi_arch[1] in ['ia32', 'x86_64'] - stub_sources += 'linux_x86.c' + stub_sources += files('linux_x86.c') else - stub_sources += 'linux.c' + stub_sources += files('linux.c') endif # BCD parser only makes sense on arches that Windows supports. if efi_arch[1] in ['ia32', 'x86_64', 'arm', 'aarch64'] - systemd_boot_sources += 'bcd.c' + systemd_boot_sources += files('bcd.c') tests += [ [['src/boot/efi/test-bcd.c'], [], @@ -359,9 +363,10 @@ endif systemd_boot_objects = [] stub_objects = [] foreach file : fundamental_source_paths + common_sources + systemd_boot_sources + stub_sources - o_file = custom_target(file.split('/')[-1] + '.o', + # FIXME: replace ''.format(file) with fs.name(file) when meson_version requirement is >= 0.59.0 + o_file = custom_target('@0@.o'.format(file).split('/')[-1], input : file, - output : file.split('/')[-1] + '.o', + output : '@0@.o'.format(file).split('/')[-1], command : [cc.cmd_array(), '-c', '@INPUT@', '-o', '@OUTPUT@', efi_cflags], depend_files : efi_headers + fundamental_headers) if (fundamental_source_paths + common_sources + systemd_boot_sources).contains(file) diff --git a/src/fundamental/meson.build b/src/fundamental/meson.build index 287f0fe36ad..f927788c3ad 100644 --- a/src/fundamental/meson.build +++ b/src/fundamental/meson.build @@ -8,20 +8,16 @@ fundamental_headers = files( 'macro-fundamental.h', 'sha256.h', 'string-util-fundamental.h', - 'types-fundamental.h') - -sources = ''' - bootspec-fundamental.c - efivars-fundamental.c - string-util-fundamental.c - sha256.c -'''.split() + 'types-fundamental.h', +) # for sd-boot -fundamental_source_paths = [] -foreach source : sources - fundamental_source_paths += meson.current_source_dir() / source -endforeach +fundamental_source_paths = files( + 'bootspec-fundamental.c', + 'efivars-fundamental.c', + 'sha256.c', + 'string-util-fundamental.c', +) # for libbasic -fundamental_sources = files(sources) + fundamental_headers +fundamental_sources = fundamental_source_paths + fundamental_headers From 904ea229815739401ddfa26074cef5d008e036f6 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Tue, 11 Jan 2022 10:21:23 +0100 Subject: [PATCH 24/41] meson: Use files() for tests Not having to provide the full path in the source tree is much nicer and the produced lists can also be used anywhere in the source tree. (cherry picked from commit e1eeebbb11ca0eca5dfd2ce32a928ee5174ea7ff) Related: #2013213 --- meson.build | 3 +- src/analyze/meson.build | 6 +- src/boot/efi/meson.build | 2 +- src/busctl/meson.build | 6 +- src/coredump/meson.build | 6 +- src/import/meson.build | 6 +- src/journal/meson.build | 14 +- src/libsystemd-network/meson.build | 22 +- src/libsystemd/meson.build | 70 ++--- src/libudev/meson.build | 2 +- src/locale/meson.build | 6 +- src/login/meson.build | 6 +- src/machine/meson.build | 2 +- src/network/meson.build | 16 +- src/nspawn/meson.build | 4 +- src/oom/meson.build | 6 +- src/resolve/meson.build | 16 +- src/shutdown/meson.build | 6 +- src/test/meson.build | 386 ++++++++++++------------ src/timesync/meson.build | 2 +- src/tmpfiles/meson.build | 6 +- src/udev/meson.build | 16 +- src/xdg-autostart-generator/meson.build | 6 +- 23 files changed, 308 insertions(+), 307 deletions(-) diff --git a/meson.build b/meson.build index f040eeab99c..35ba29aecfe 100644 --- a/meson.build +++ b/meson.build @@ -3566,7 +3566,8 @@ foreach tuple : tests parallel = tuple.length() > 7 ? tuple[7] : true timeout = 30 - name = sources[0].split('/')[-1].split('.')[0] + # FIXME: Use fs.stem() with meson >= 0.54.0 + name = '@0@'.format(sources[0]).split('/')[-1].split('.')[0] if type.startswith('timeout=') timeout = type.split('=')[1].to_int() type = '' diff --git a/src/analyze/meson.build b/src/analyze/meson.build index 492b79069fb..fbc4d7e20dd 100644 --- a/src/analyze/meson.build +++ b/src/analyze/meson.build @@ -13,9 +13,9 @@ systemd_analyze_sources = files(''' '''.split()) tests += [ - [['src/analyze/test-verify.c', - 'src/analyze/analyze-verify.c', - 'src/analyze/analyze-verify.h'], + [files('test-verify.c', + 'analyze-verify.c', + 'analyze-verify.h'), [libcore, libshared], [], diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build index 4cc43dc00ce..16b34f0ac26 100644 --- a/src/boot/efi/meson.build +++ b/src/boot/efi/meson.build @@ -352,7 +352,7 @@ endif if efi_arch[1] in ['ia32', 'x86_64', 'arm', 'aarch64'] systemd_boot_sources += files('bcd.c') tests += [ - [['src/boot/efi/test-bcd.c'], + [files('test-bcd.c'), [], [libzstd], [], diff --git a/src/busctl/meson.build b/src/busctl/meson.build index f463436fab1..295dc0926da 100644 --- a/src/busctl/meson.build +++ b/src/busctl/meson.build @@ -6,7 +6,7 @@ busctl_sources = files( 'busctl.c') tests += [ - [['src/busctl/test-busctl-introspect.c', - 'src/busctl/busctl-introspect.c', - 'src/busctl/busctl-introspect.h']], + [files('test-busctl-introspect.c', + 'busctl-introspect.c', + 'busctl-introspect.h')], ] diff --git a/src/coredump/meson.build b/src/coredump/meson.build index b832192c9f9..49ea93965bd 100644 --- a/src/coredump/meson.build +++ b/src/coredump/meson.build @@ -14,8 +14,8 @@ if conf.get('ENABLE_COREDUMP') == 1 and install_sysconfdir_samples endif tests += [ - [['src/coredump/test-coredump-vacuum.c', - 'src/coredump/coredump-vacuum.c', - 'src/coredump/coredump-vacuum.h'], + [files('test-coredump-vacuum.c', + 'coredump-vacuum.c', + 'coredump-vacuum.h'), [], [], [], '', 'manual'], ] diff --git a/src/import/meson.build b/src/import/meson.build index 23f08588170..7e923072a9b 100644 --- a/src/import/meson.build +++ b/src/import/meson.build @@ -61,9 +61,9 @@ if conf.get('ENABLE_IMPORTD') == 1 endif tests += [ - [['src/import/test-qcow2.c', - 'src/import/qcow2-util.c', - 'src/import/qcow2-util.h'], + [files('test-qcow2.c', + 'qcow2-util.c', + 'qcow2-util.h'), [], [libz], [], 'HAVE_ZLIB', 'manual'], diff --git a/src/journal/meson.build b/src/journal/meson.build index 270592f2aca..b9a63d5e2fe 100644 --- a/src/journal/meson.build +++ b/src/journal/meson.build @@ -79,7 +79,7 @@ endif ############################################################ tests += [ - [['src/journal/test-journal-syslog.c'], + [files('test-journal-syslog.c'), [libjournal_core, libshared], [threads, @@ -87,30 +87,30 @@ tests += [ liblz4, libselinux]], - [['src/journal/test-journal-config.c'], + [files('test-journal-config.c'), [libjournal_core, libshared], [libxz, liblz4, libselinux]], - [['src/journal/test-journal.c'], + [files('test-journal.c'), [libjournal_core, libshared]], - [['src/journal/test-journal-stream.c'], + [files('test-journal-stream.c'), [libjournal_core, libshared]], - [['src/journal/test-journal-flush.c'], + [files('test-journal-flush.c'), [libjournal_core, libshared]], - [['src/journal/test-journal-verify.c'], + [files('test-journal-verify.c'), [libjournal_core, libshared]], - [['src/journal/test-journal-interleaving.c'], + [files('test-journal-interleaving.c'), [libjournal_core, libshared]], ] diff --git a/src/libsystemd-network/meson.build b/src/libsystemd-network/meson.build index a7838cdaa1d..3923df48ea4 100644 --- a/src/libsystemd-network/meson.build +++ b/src/libsystemd-network/meson.build @@ -57,49 +57,49 @@ libsystemd_network_includes = [includes, include_directories('.')] ############################################################ tests += [ - [['src/libsystemd-network/test-dhcp-option.c'], + [files('test-dhcp-option.c'), [libshared, libsystemd_network]], - [['src/libsystemd-network/test-sd-dhcp-lease.c'], + [files('test-sd-dhcp-lease.c'), [libshared, libsystemd_network]], - [['src/libsystemd-network/test-dhcp-client.c'], + [files('test-dhcp-client.c'), [libshared, libsystemd_network]], - [['src/libsystemd-network/test-dhcp-server.c'], + [files('test-dhcp-server.c'), [libshared, libsystemd_network]], - [['src/libsystemd-network/test-ipv4ll.c'], + [files('test-ipv4ll.c'), [libshared, libsystemd_network]], - [['src/libsystemd-network/test-ipv4ll-manual.c'], + [files('test-ipv4ll-manual.c'), [libshared, libsystemd_network], [], [], '', 'manual'], - [['src/libsystemd-network/test-acd.c'], + [files('test-acd.c'), [libshared, libsystemd_network], [], [], '', 'manual'], - [['src/libsystemd-network/test-ndisc-rs.c'], + [files('test-ndisc-rs.c'), [libshared, libsystemd_network]], - [['src/libsystemd-network/test-ndisc-ra.c'], + [files('test-ndisc-ra.c'), [libshared, libsystemd_network]], - [['src/libsystemd-network/test-dhcp6-client.c'], + [files('test-dhcp6-client.c'), [libshared, libsystemd_network]], - [['src/libsystemd-network/test-lldp-rx.c'], + [files('test-lldp-rx.c'), [libshared, libsystemd_network]], ] diff --git a/src/libsystemd/meson.build b/src/libsystemd/meson.build index 124393d3e67..42746e560f3 100644 --- a/src/libsystemd/meson.build +++ b/src/libsystemd/meson.build @@ -190,43 +190,43 @@ custom_target( ############################################################ tests += [ - [['src/libsystemd/sd-journal/test-journal-send.c']], + [files('sd-journal/test-journal-send.c')], - [['src/libsystemd/sd-journal/test-journal-match.c']], + [files('sd-journal/test-journal-match.c')], - [['src/libsystemd/sd-journal/test-journal-enum.c'], + [files('sd-journal/test-journal-enum.c'), [], [], [], '', 'timeout=360'], - [['src/libsystemd/sd-journal/test-journal-init.c']], + [files('sd-journal/test-journal-init.c')], - [['src/libsystemd/sd-journal/test-mmap-cache.c']], + [files('sd-journal/test-mmap-cache.c')], - [['src/libsystemd/sd-journal/test-catalog.c']], + [files('sd-journal/test-catalog.c')], - [['src/libsystemd/sd-journal/test-compress.c'], + [files('sd-journal/test-compress.c'), [], [liblz4, libzstd, libxz]], - [['src/libsystemd/sd-journal/test-compress-benchmark.c'], + [files('sd-journal/test-compress-benchmark.c'), [], [liblz4, libzstd, libxz], [], '', 'timeout=90'], - [['src/libsystemd/sd-journal/test-audit-type.c']], + [files('sd-journal/test-audit-type.c')], ] ############################################################ tests += [ - [['src/libsystemd/sd-bus/test-bus-address.c'], + [files('sd-bus/test-bus-address.c'), [], [threads]], - [['src/libsystemd/sd-bus/test-bus-marshal.c'], + [files('sd-bus/test-bus-marshal.c'), [], [threads, libglib, @@ -234,82 +234,82 @@ tests += [ libgio, libdbus]], - [['src/libsystemd/sd-bus/test-bus-signature.c'], + [files('sd-bus/test-bus-signature.c'), [], [threads]], - [['src/libsystemd/sd-bus/test-bus-queue-ref-cycle.c'], + [files('sd-bus/test-bus-queue-ref-cycle.c'), [], [threads]], - [['src/libsystemd/sd-bus/test-bus-watch-bind.c'], + [files('sd-bus/test-bus-watch-bind.c'), [], [threads], [], '', 'timeout=120'], - [['src/libsystemd/sd-bus/test-bus-chat.c'], + [files('sd-bus/test-bus-chat.c'), [], [threads]], - [['src/libsystemd/sd-bus/test-bus-cleanup.c'], + [files('sd-bus/test-bus-cleanup.c'), [], [threads, libseccomp]], - [['src/libsystemd/sd-bus/test-bus-track.c'], + [files('sd-bus/test-bus-track.c'), [], [libseccomp]], - [['src/libsystemd/sd-bus/test-bus-server.c'], + [files('sd-bus/test-bus-server.c'), [], [threads]], - [['src/libsystemd/sd-bus/test-bus-objects.c'], + [files('sd-bus/test-bus-objects.c'), [], [threads]], - [['src/libsystemd/sd-bus/test-bus-vtable.c', - 'src/libsystemd/sd-bus/test-vtable-data.h']], + [files('sd-bus/test-bus-vtable.c', + 'sd-bus/test-vtable-data.h')], - [['src/libsystemd/sd-bus/test-bus-gvariant.c'], + [files('sd-bus/test-bus-gvariant.c'), [], [libglib, libgobject, libgio]], - [['src/libsystemd/sd-bus/test-bus-creds.c']], + [files('sd-bus/test-bus-creds.c')], - [['src/libsystemd/sd-bus/test-bus-match.c']], + [files('sd-bus/test-bus-match.c')], - [['src/libsystemd/sd-bus/test-bus-benchmark.c'], + [files('sd-bus/test-bus-benchmark.c'), [], [threads], [], '', 'manual'], - [['src/libsystemd/sd-bus/test-bus-introspect.c', - 'src/libsystemd/sd-bus/test-vtable-data.h']], + [files('sd-bus/test-bus-introspect.c', + 'sd-bus/test-vtable-data.h')], - [['src/libsystemd/sd-event/test-event.c']], + [files('sd-event/test-event.c')], - [['src/libsystemd/sd-netlink/test-netlink.c']], + [files('sd-netlink/test-netlink.c')], - [['src/libsystemd/sd-resolve/test-resolve.c'], + [files('sd-resolve/test-resolve.c'), [], [threads], [], '', 'timeout=120'], - [['src/libsystemd/sd-login/test-login.c']], + [files('sd-login/test-login.c')], - [['src/libsystemd/sd-device/test-sd-device.c']], + [files('sd-device/test-sd-device.c')], - [['src/libsystemd/sd-device/test-device-util.c']], + [files('sd-device/test-device-util.c')], - [['src/libsystemd/sd-device/test-sd-device-monitor.c']], + [files('sd-device/test-sd-device-monitor.c')], ] if cxx_cmd != '' tests += [ - [['src/libsystemd/sd-bus/test-bus-vtable-cc.cc']], + [files('sd-bus/test-bus-vtable-cc.cc')], ] endif diff --git a/src/libudev/meson.build b/src/libudev/meson.build index 77b31a9492e..2d51ff7c583 100644 --- a/src/libudev/meson.build +++ b/src/libudev/meson.build @@ -45,7 +45,7 @@ custom_target( ############################################################ tests += [ - [['src/libudev/test-libudev.c'], + [files('test-libudev.c'), [libshared, libudev_basic]], ] diff --git a/src/locale/meson.build b/src/locale/meson.build index a2ff2a98736..0ccf71583da 100644 --- a/src/locale/meson.build +++ b/src/locale/meson.build @@ -30,7 +30,7 @@ if conf.get('ENABLE_LOCALED') == 1 endif tests += [ - [['src/locale/test-keymap-util.c', - 'src/locale/keymap-util.c', - 'src/locale/keymap-util.h']], + [files('test-keymap-util.c', + 'keymap-util.c', + 'keymap-util.h')], ] diff --git a/src/login/meson.build b/src/login/meson.build index a78c2bc2dd6..92f491665cd 100644 --- a/src/login/meson.build +++ b/src/login/meson.build @@ -101,12 +101,12 @@ endif ############################################################ tests += [ - [['src/login/test-login-shared.c']], + [files('test-login-shared.c')], - [['src/login/test-inhibit.c'], + [files('test-inhibit.c'), [], [], [], '', 'manual'], - [['src/login/test-login-tables.c'], + [files('test-login-tables.c'), [liblogind_core, libshared], [threads]], diff --git a/src/machine/meson.build b/src/machine/meson.build index ef858a5988f..87e4dde24ce 100644 --- a/src/machine/meson.build +++ b/src/machine/meson.build @@ -37,7 +37,7 @@ if conf.get('ENABLE_MACHINED') == 1 endif tests += [ - [['src/machine/test-machine-tables.c'], + [files('test-machine-tables.c'), [libmachine_core, libshared], [threads]], diff --git a/src/network/meson.build b/src/network/meson.build index 5857439c5ab..a598701e4fe 100644 --- a/src/network/meson.build +++ b/src/network/meson.build @@ -277,37 +277,37 @@ fuzzers += [ ] tests += [ - [['src/network/test-networkd-address.c'], + [files('test-networkd-address.c'), [libnetworkd_core, libsystemd_network], [], network_includes], - [['src/network/test-networkd-conf.c'], + [files('test-networkd-conf.c'), [libnetworkd_core, libsystemd_network], [], network_includes], - [['src/network/test-networkd-util.c'], + [files('test-networkd-util.c'), [libnetworkd_core, libsystemd_network], [], network_includes], - [['src/network/test-network.c'], + [files('test-network.c'), [libnetworkd_core, libsystemd_network], [threads], network_includes], - [['src/network/test-network-tables.c'], + [files('test-network-tables.c'), [libnetworkd_core, libsystemd_network], [threads], network_includes], - [['src/network/generator/test-network-generator.c', - 'src/network/generator/network-generator.c', - 'src/network/generator/network-generator.h']], + [files('generator/test-network-generator.c', + 'generator/network-generator.c', + 'generator/network-generator.h')], ] diff --git a/src/nspawn/meson.build b/src/nspawn/meson.build index 11ac404e999..3c1a9c61827 100644 --- a/src/nspawn/meson.build +++ b/src/nspawn/meson.build @@ -53,12 +53,12 @@ systemd_nspawn_sources = files('nspawn.c') ############################################################ tests += [ - [['src/nspawn/test-nspawn-tables.c'], + [files('test-nspawn-tables.c'), [libnspawn_core, libshared], [libseccomp]], - [['src/nspawn/test-patch-uid.c'], + [files('test-patch-uid.c'), [libnspawn_core, libshared], [libacl], diff --git a/src/oom/meson.build b/src/oom/meson.build index 4e1c8543c8c..da00cbf99e0 100644 --- a/src/oom/meson.build +++ b/src/oom/meson.build @@ -28,7 +28,7 @@ if conf.get('ENABLE_OOMD') == 1 endif tests += [ - [['src/oom/test-oomd-util.c', - 'src/oom/oomd-util.c', - 'src/oom/oomd-util.h']], + [files('test-oomd-util.c', + 'oomd-util.c', + 'oomd-util.h')], ] diff --git a/src/resolve/meson.build b/src/resolve/meson.build index 2cdf24b1cbe..4de50c3d8e5 100644 --- a/src/resolve/meson.build +++ b/src/resolve/meson.build @@ -174,40 +174,40 @@ custom_target( ############################################################ tests += [ - [['src/resolve/test-resolve-tables.c'], + [files('test-resolve-tables.c'), [libsystemd_resolve_core, libshared], [lib_openssl_or_gcrypt, libm]], - [['src/resolve/test-dns-packet.c'], + [files('test-dns-packet.c'), [libsystemd_resolve_core, libshared], [lib_openssl_or_gcrypt, libm]], - [['src/resolve/test-resolved-etc-hosts.c', - 'src/resolve/resolved-etc-hosts.c', - 'src/resolve/resolved-etc-hosts.h'], + [files('test-resolved-etc-hosts.c', + 'resolved-etc-hosts.c', + 'resolved-etc-hosts.h'), [libsystemd_resolve_core, libshared], [lib_openssl_or_gcrypt, libm]], - [['src/resolve/test-resolved-packet.c'], + [files('test-resolved-packet.c'), [libsystemd_resolve_core, libshared], [lib_openssl_or_gcrypt, libm]], - [['src/resolve/test-dnssec.c'], + [files('test-dnssec.c'), [libsystemd_resolve_core, libshared], [lib_openssl_or_gcrypt, libm], [], 'HAVE_OPENSSL_OR_GCRYPT'], - [['src/resolve/test-dnssec-complex.c'], + [files('test-dnssec-complex.c'), [libsystemd_resolve_core, libshared], [lib_openssl_or_gcrypt, diff --git a/src/shutdown/meson.build b/src/shutdown/meson.build index e1348d95d42..fcc9f9f0ac9 100644 --- a/src/shutdown/meson.build +++ b/src/shutdown/meson.build @@ -7,9 +7,9 @@ systemd_shutdown_sources = files(''' '''.split()) tests += [ - [['src/shutdown/test-umount.c', - 'src/shutdown/umount.c', - 'src/shutdown/umount.h'], + [files('test-umount.c', + 'umount.c', + 'umount.h'), [], [libmount]], ] diff --git a/src/test/meson.build b/src/test/meson.build index 48001d17ecc..9e224d69ce8 100644 --- a/src/test/meson.build +++ b/src/test/meson.build @@ -41,11 +41,11 @@ test_dlopen_c = files('test-dlopen.c') ############################################################ tests += [ - [['src/test/test-device-nodes.c']], + [files('test-device-nodes.c')], - [['src/test/test-ether-addr-util.c']], + [files('test-ether-addr-util.c')], - [['src/test/test-engine.c'], + [files('test-engine.c'), [libcore, libshared], [threads, @@ -56,21 +56,21 @@ tests += [ libblkid], core_includes], - [['src/test/test-emergency-action.c'], + [files('test-emergency-action.c'), [libcore, libshared], [], core_includes], - [['src/test/test-chown-rec.c'], + [files('test-chown-rec.c'), [libcore, libshared], [], core_includes], - [['src/test/test-dlopen-so.c']], + [files('test-dlopen-so.c')], - [['src/test/test-job-type.c'], + [files('test-job-type.c'), [libcore, libshared], [threads, @@ -81,7 +81,7 @@ tests += [ libblkid], core_includes], - [['src/test/test-ns.c'], + [files('test-ns.c'), [libcore, libshared], [threads, @@ -92,7 +92,7 @@ tests += [ libblkid], core_includes, '', 'manual'], - [['src/test/test-loopback.c'], + [files('test-loopback.c'), [libcore, libshared], [threads, @@ -103,14 +103,14 @@ tests += [ libblkid], core_includes], - [['src/test/test-dns-domain.c']], + [files('test-dns-domain.c')], - [['src/test/test-boot-timestamps.c'], + [files('test-boot-timestamps.c'), [], [], [], 'ENABLE_EFI'], - [['src/test/test-unit-file.c']], + [files('test-unit-file.c')], - [['src/test/test-unit-name.c'], + [files('test-unit-name.c'), [libcore, libshared], [threads, @@ -121,7 +121,7 @@ tests += [ libblkid], core_includes], - [['src/test/test-load-fragment.c'], + [files('test-load-fragment.c'), [libcore, libshared], [threads, @@ -132,9 +132,9 @@ tests += [ libblkid], core_includes], - [['src/test/test-serialize.c']], + [files('test-serialize.c')], - [['src/test/test-unit-serialize.c'], + [files('test-unit-serialize.c'), [libcore, libshared], [threads, @@ -145,196 +145,196 @@ tests += [ libblkid], core_includes], - [['src/test/test-utf8.c']], + [files('test-utf8.c')], - [['src/test/test-kbd-util.c']], + [files('test-kbd-util.c')], - [['src/test/test-blockdev-util.c']], + [files('test-blockdev-util.c')], - [['src/test/test-dev-setup.c']], + [files('test-dev-setup.c')], - [['src/test/test-capability.c'], + [files('test-capability.c'), [], [libcap]], - [['src/test/test-async.c'], + [files('test-async.c'), [], [], [], '', 'timeout=120'], - [['src/test/test-locale-util.c']], + [files('test-locale-util.c')], - [['src/test/test-copy.c']], + [files('test-copy.c')], - [['src/test/test-recurse-dir.c']], + [files('test-recurse-dir.c')], - [['src/test/test-data-fd-util.c']], + [files('test-data-fd-util.c')], - [['src/test/test-static-destruct.c']], + [files('test-static-destruct.c')], - [['src/test/test-sigbus.c']], + [files('test-sigbus.c')], - [['src/test/test-condition.c']], + [files('test-condition.c')], - [['src/test/test-fdset.c']], + [files('test-fdset.c')], - [['src/test/test-fstab-util.c']], + [files('test-fstab-util.c')], - [['src/test/test-random-util.c'], + [files('test-random-util.c'), [], [libm], [], '', 'timeout=120'], - [['src/test/test-format-table.c']], + [files('test-format-table.c')], - [['src/test/test-format-util.c']], + [files('test-format-util.c')], - [['src/test/test-ratelimit.c']], + [files('test-ratelimit.c')], - [['src/test/test-util.c']], + [files('test-util.c')], - [['src/test/test-macro.c']], + [files('test-macro.c')], - [['src/test/test-json.c']], + [files('test-json.c')], - [['src/test/test-modhex.c']], + [files('test-modhex.c')], - [['src/test/test-libmount.c'], + [files('test-libmount.c'), [], [threads, libmount]], - [['src/test/test-mount-util.c']], + [files('test-mount-util.c')], - [['src/test/test-mountpoint-util.c']], + [files('test-mountpoint-util.c')], - [['src/test/test-exec-util.c']], + [files('test-exec-util.c')], - [['src/test/test-hexdecoct.c']], + [files('test-hexdecoct.c')], - [['src/test/test-alloc-util.c']], + [files('test-alloc-util.c')], - [['src/test/test-xattr-util.c']], + [files('test-xattr-util.c')], - [['src/test/test-io-util.c']], + [files('test-io-util.c')], - [['src/test/test-glob-util.c']], + [files('test-glob-util.c')], - [['src/test/test-fs-util.c']], + [files('test-fs-util.c')], - [['src/test/test-install-file.c']], + [files('test-install-file.c')], - [['src/test/test-umask-util.c']], + [files('test-umask-util.c')], - [['src/test/test-proc-cmdline.c']], + [files('test-proc-cmdline.c')], - [['src/test/test-fd-util.c'], + [files('test-fd-util.c'), [], [libseccomp]], - [['src/test/test-web-util.c']], + [files('test-web-util.c')], - [['src/test/test-cpu-set-util.c']], + [files('test-cpu-set-util.c')], - [['src/test/test-stat-util.c']], + [files('test-stat-util.c')], - [['src/test/test-os-util.c']], + [files('test-os-util.c')], - [['src/test/test-libcrypt-util.c'], + [files('test-libcrypt-util.c'), [], [libcrypt], [], '', 'timeout=120'], - [['src/test/test-escape.c']], + [files('test-escape.c')], - [['src/test/test-exit-status.c']], + [files('test-exit-status.c')], - [['src/test/test-specifier.c']], + [files('test-specifier.c')], - [['src/test/test-string-util.c']], + [files('test-string-util.c')], - [['src/test/test-extract-word.c']], + [files('test-extract-word.c')], - [['src/test/test-parse-argument.c']], + [files('test-parse-argument.c')], - [['src/test/test-parse-socket-bind-item.c']], + [files('test-parse-socket-bind-item.c')], - [['src/test/test-parse-util.c']], + [files('test-parse-util.c')], - [['src/test/test-sysctl-util.c']], + [files('test-sysctl-util.c')], - [['src/test/test-import-util.c']], + [files('test-import-util.c')], - [['src/test/test-uid-alloc-range.c']], + [files('test-uid-alloc-range.c')], - [['src/test/test-user-util.c']], + [files('test-user-util.c')], - [['src/test/test-hostname-setup.c']], + [files('test-hostname-setup.c')], - [['src/test/test-hostname-util.c']], + [files('test-hostname-util.c')], - [['src/test/test-process-util.c']], + [files('test-process-util.c')], - [['src/test/test-terminal-util.c']], + [files('test-terminal-util.c')], - [['src/test/test-path-lookup.c']], + [files('test-path-lookup.c')], - [['src/test/test-pretty-print.c']], + [files('test-pretty-print.c')], - [['src/test/test-uid-range.c']], + [files('test-uid-range.c')], - [['src/test/test-cap-list.c', - generated_gperf_headers], + [files('test-cap-list.c') + + generated_gperf_headers, [], [libcap]], - [['src/test/test-socket-util.c']], + [files('test-socket-util.c')], - [['src/test/test-socket-netlink.c']], + [files('test-socket-netlink.c')], - [['src/test/test-in-addr-util.c']], + [files('test-in-addr-util.c')], - [['src/test/test-in-addr-prefix-util.c']], + [files('test-in-addr-prefix-util.c')], - [['src/test/test-barrier.c']], + [files('test-barrier.c')], - [['src/test/test-tmpfiles.c']], + [files('test-tmpfiles.c')], - [['src/test/test-namespace.c'], + [files('test-namespace.c'), [libcore, libshared], [threads, libblkid], core_includes], - [['src/test/test-verbs.c']], + [files('test-verbs.c')], - [['src/test/test-install-root.c']], + [files('test-install-root.c')], - [['src/test/test-acl-util.c'], + [files('test-acl-util.c'), [], [], [], 'HAVE_ACL'], - [['src/test/test-seccomp.c'], + [files('test-seccomp.c'), [], [libseccomp], [], 'HAVE_SECCOMP'], - [['src/test/test-rlimit-util.c']], + [files('test-rlimit-util.c')], - [['src/test/test-ask-password-api.c'], + [files('test-ask-password-api.c'), [], [], [], '', 'manual'], - [['src/test/test-signal-util.c']], + [files('test-signal-util.c')], - [['src/test/test-loop-block.c'], + [files('test-loop-block.c'), [libcore, libshared], [threads, libblkid], core_includes, '', '', [], false], - [['src/test/test-selinux.c']], + [files('test-selinux.c')], - [['src/test/test-sizeof.c'], + [files('test-sizeof.c'), [libbasic]], - [['src/test/test-bpf-devices.c'], + [files('test-bpf-devices.c'), [libcore, libshared], [libmount, @@ -345,7 +345,7 @@ tests += [ libblkid], core_includes], - [['src/test/test-bpf-firewall.c'], + [files('test-bpf-firewall.c'), [libcore, libshared], [libmount, @@ -356,13 +356,13 @@ tests += [ libblkid], core_includes], - [['src/test/test-bpf-foreign-programs.c'], + [files('test-bpf-foreign-programs.c'), [libcore, libshared], [], core_includes], - [['src/test/test-bpf-lsm.c'], + [files('test-bpf-lsm.c'), [libcore, libshared], [libmount, @@ -373,7 +373,7 @@ tests += [ libblkid], core_includes], - [['src/test/test-watch-pid.c'], + [files('test-watch-pid.c'), [libcore, libshared], [libmount, @@ -384,32 +384,32 @@ tests += [ libblkid], core_includes], - [['src/test/test-hashmap.c', - 'src/test/test-hashmap-plain.c', - test_hashmap_ordered_c], + [files('test-hashmap.c', + 'test-hashmap-plain.c') + + [test_hashmap_ordered_c], [], [], [], '', 'timeout=180'], - [['src/test/test-set.c']], + [files('test-set.c')], - [['src/test/test-ordered-set.c']], + [files('test-ordered-set.c')], - [['src/test/test-set-disable-mempool.c'], + [files('test-set-disable-mempool.c'), [], [threads]], - [['src/test/test-hash-funcs.c']], + [files('test-hash-funcs.c')], - [['src/test/test-bitmap.c']], + [files('test-bitmap.c')], - [['src/test/test-xml.c']], + [files('test-xml.c')], - [['src/test/test-list.c']], + [files('test-list.c')], - [['src/test/test-procfs-util.c']], + [files('test-procfs-util.c')], - [['src/test/test-unaligned.c']], + [files('test-unaligned.c')], - [['src/test/test-tables.c'], + [files('test-tables.c'), [libcore, libjournal_core, libudevd_core, @@ -422,70 +422,70 @@ tests += [ libblkid], [core_includes, journal_includes, udev_includes]], - [['src/test/test-prioq.c']], + [files('test-prioq.c')], - [['src/test/test-fileio.c']], + [files('test-fileio.c')], - [['src/test/test-time-util.c']], + [files('test-time-util.c')], - [['src/test/test-clock.c']], + [files('test-clock.c')], - [['src/test/test-tmpfile-util.c']], + [files('test-tmpfile-util.c')], - [['src/test/test-architecture.c']], + [files('test-architecture.c')], - [['src/test/test-gpt.c']], + [files('test-gpt.c')], - [['src/test/test-log.c']], + [files('test-log.c')], - [['src/test/test-ipcrm.c'], + [files('test-ipcrm.c'), [], [], [], '', 'unsafe'], - [['src/test/test-btrfs.c'], + [files('test-btrfs.c'), [], [], [], '', 'manual'], - [['src/test/test-firewall-util.c']], + [files('test-firewall-util.c')], - [['src/test/test-net-naming-scheme.c']], + [files('test-net-naming-scheme.c')], - [['src/test/test-netlink-manual.c'], + [files('test-netlink-manual.c'), [], [libkmod], [], 'HAVE_KMOD', 'manual'], - [['src/test/test-ellipsize.c']], + [files('test-ellipsize.c')], - [['src/test/test-date.c']], + [files('test-date.c')], - [['src/test/test-sleep.c']], + [files('test-sleep.c')], - [['src/test/test-tpm2.c']], + [files('test-tpm2.c')], - [['src/test/test-replace-var.c']], + [files('test-replace-var.c')], - [['src/test/test-calendarspec.c']], + [files('test-calendarspec.c')], - [['src/test/test-strip-tab-ansi.c']], + [files('test-strip-tab-ansi.c')], - [['src/test/test-coredump-util.c']], + [files('test-coredump-util.c')], - [['src/test/test-daemon.c']], + [files('test-daemon.c')], - [['src/test/test-cgroup.c']], + [files('test-cgroup.c')], - [['src/test/test-cgroup-cpu.c'], + [files('test-cgroup-cpu.c'), [libcore, libshared], [], core_includes], - [['src/test/test-cgroup-unit-default.c'], + [files('test-cgroup-unit-default.c'), [libcore, libshared], [], core_includes], - [['src/test/test-cgroup-mask.c'], + [files('test-cgroup-mask.c'), [libcore, libshared], [threads, @@ -496,30 +496,30 @@ tests += [ libblkid], core_includes], - [['src/test/test-varlink.c'], + [files('test-varlink.c'), [], [threads]], - [['src/test/test-cgroup-util.c']], + [files('test-cgroup-util.c')], - [['src/test/test-cgroup-setup.c']], + [files('test-cgroup-setup.c')], - [['src/test/test-env-file.c']], + [files('test-env-file.c')], - [['src/test/test-env-util.c']], + [files('test-env-util.c')], - [['src/test/test-strbuf.c']], + [files('test-strbuf.c')], - [['src/test/test-strv.c']], + [files('test-strv.c')], - [['src/test/test-path-util.c']], + [files('test-path-util.c')], - [['src/test/test-rm-rf.c']], + [files('test-rm-rf.c')], - [['src/test/test-chase-symlinks.c'], + [files('test-chase-symlinks.c'), [], [], [], '', 'manual'], - [['src/test/test-path.c'], + [files('test-path.c'), [libcore, libshared], [threads, @@ -530,7 +530,7 @@ tests += [ libblkid], core_includes, '', 'timeout=120'], - [['src/test/test-execute.c'], + [files('test-execute.c'), [libcore, libshared], [threads, @@ -541,20 +541,20 @@ tests += [ libblkid], core_includes, '', 'timeout=360'], - [['src/test/test-siphash24.c']], + [files('test-siphash24.c')], - [['src/test/test-strxcpyx.c']], + [files('test-strxcpyx.c')], - [['src/test/test-install.c'], + [files('test-install.c'), [libcore, libshared], [], core_includes, '', 'manual'], - [['src/test/test-watchdog.c'], + [files('test-watchdog.c'), [], [], [], '', 'unsafe'], - [['src/test/test-sched-prio.c'], + [files('test-sched-prio.c'), [libcore, libshared], [threads, @@ -565,25 +565,25 @@ tests += [ libblkid], core_includes], - [['src/test/test-conf-files.c']], + [files('test-conf-files.c')], - [['src/test/test-conf-parser.c']], + [files('test-conf-parser.c')], - [['src/test/test-af-list.c', - generated_gperf_headers]], + [files('test-af-list.c') + + generated_gperf_headers], - [['src/test/test-arphrd-util.c', - generated_gperf_headers]], + [files('test-arphrd-util.c') + + generated_gperf_headers], - [['src/test/test-errno-list.c', - generated_gperf_headers]], + [files('test-errno-list.c') + + generated_gperf_headers], - [['src/test/test-ip-protocol-list.c', - shared_generated_gperf_headers]], + [files('test-ip-protocol-list.c') + + shared_generated_gperf_headers], - [['src/test/test-journal-importer.c']], + [files('test-journal-importer.c')], - [['src/test/test-udev.c'], + [files('test-udev.c'), [libudevd_core, libshared], [threads, @@ -594,49 +594,49 @@ tests += [ libselinux], udev_includes, '', 'manual'], - [['src/test/test-udev-util.c']], + [files('test-udev-util.c')], - [['src/test/test-id128.c']], + [files('test-id128.c')], - [['src/test/test-cryptolib.c'], + [files('test-cryptolib.c'), [libshared], [lib_openssl_or_gcrypt], [], 'HAVE_OPENSSL_OR_GCRYPT'], - [['src/test/test-nss-hosts.c', - 'src/test/nss-test-util.c', - 'src/test/nss-test-util.h'], + [files('test-nss-hosts.c', + 'nss-test-util.c', + 'nss-test-util.h'), [], [libdl], [], 'ENABLE_NSS', 'manual'], - [['src/test/test-nss-users.c', - 'src/test/nss-test-util.c', - 'src/test/nss-test-util.h'], + [files('test-nss-users.c', + 'nss-test-util.c', + 'nss-test-util.h'), [], [libdl], [], 'ENABLE_NSS', 'manual'], - [['src/test/test-bus-util.c']], + [files('test-bus-util.c')], - [['src/test/test-percent-util.c']], + [files('test-percent-util.c')], - [['src/test/test-sd-hwdb.c']], + [files('test-sd-hwdb.c')], - [['src/test/test-sd-path.c']], + [files('test-sd-path.c')], - [['src/test/test-local-addresses.c']], + [files('test-local-addresses.c')], - [['src/test/test-psi-util.c']], + [files('test-psi-util.c')], - [['src/test/test-qrcode-util.c'], + [files('test-qrcode-util.c'), [], [libdl]], - [['src/test/test-nscd-flush.c'], + [files('test-nscd-flush.c'), [], [], [], 'ENABLE_NSCD', 'manual'], - [['src/test/test-hmac.c']], + [files('test-hmac.c')], ] ############################################################ @@ -644,23 +644,23 @@ tests += [ # define some tests here, because the link_with deps were not defined earlier tests += [ - [['src/libsystemd/sd-bus/test-bus-error.c'], + [files('../libsystemd/sd-bus/test-bus-error.c'), [libshared_static, libsystemd_static]], - [['src/libsystemd/sd-device/test-sd-device-thread.c'], + [files('../libsystemd/sd-device/test-sd-device-thread.c'), [libsystemd], [threads]], - [['src/libudev/test-udev-device-thread.c'], + [files('../libudev/test-udev-device-thread.c'), [libudev], [threads]], ] tests += [ - [['src/test/test-socket-bind.c'], - [libcore, - libshared], + [files('test-socket-bind.c'), + [libcore, + libshared], [libdl], core_includes, 'BPF_FRAMEWORK'], diff --git a/src/timesync/meson.build b/src/timesync/meson.build index 83dd7c8f67b..8ecfbfab828 100644 --- a/src/timesync/meson.build +++ b/src/timesync/meson.build @@ -55,7 +55,7 @@ endif ############################################################ tests += [ - [['src/timesync/test-timesync.c'], + [files('test-timesync.c'), [libtimesyncd_core, libshared], [libm]], diff --git a/src/tmpfiles/meson.build b/src/tmpfiles/meson.build index c72b386cda7..cfa3d370a7a 100644 --- a/src/tmpfiles/meson.build +++ b/src/tmpfiles/meson.build @@ -6,7 +6,7 @@ systemd_tmpfiles_sources = files( 'offline-passwd.h') tests += [ - [['src/tmpfiles/test-offline-passwd.c', - 'src/tmpfiles/offline-passwd.c', - 'src/tmpfiles/offline-passwd.h']], + [files('test-offline-passwd.c', + 'offline-passwd.c', + 'offline-passwd.h')], ] diff --git a/src/udev/meson.build b/src/udev/meson.build index 29ac85da12f..57fbf8c8fc0 100644 --- a/src/udev/meson.build +++ b/src/udev/meson.build @@ -195,28 +195,28 @@ fuzzers += [ ] tests += [ - [['src/udev/test-udev-event.c'], + [files('test-udev-event.c'), [libudevd_core, libshared], [threads, libacl]], - [['src/udev/test-udev-node.c'], + [files('test-udev-node.c'), [libudevd_core, libshared], [threads, libacl]], - [['src/udev/test-udev-builtin.c'], + [files('test-udev-builtin.c'), [libudevd_core, libshared], [threads, libacl]], - [['src/udev/test-udev-netlink.c', - 'src/udev/udev-netlink.c', - 'src/udev/udev-netlink.h']], + [files('test-udev-netlink.c', + 'udev-netlink.c', + 'udev-netlink.h')], - [['src/udev/fido_id/test-fido-id-desc.c', - 'src/udev/fido_id/fido_id_desc.c']], + [files('fido_id/test-fido-id-desc.c', + 'fido_id/fido_id_desc.c')], ] diff --git a/src/xdg-autostart-generator/meson.build b/src/xdg-autostart-generator/meson.build index aa722f7f3c8..6418f57c40b 100644 --- a/src/xdg-autostart-generator/meson.build +++ b/src/xdg-autostart-generator/meson.build @@ -6,9 +6,9 @@ systemd_xdg_autostart_generator_sources = files( 'xdg-autostart-service.h') tests += [ - [['src/xdg-autostart-generator/test-xdg-autostart.c', - 'src/xdg-autostart-generator/xdg-autostart-service.c', - 'src/xdg-autostart-generator/xdg-autostart-service.h']], + [files('test-xdg-autostart.c', + 'xdg-autostart-service.c', + 'xdg-autostart-service.h')], ] fuzzers += [ From b0772787e1b94651315dfa17c0f28397f474fabc Mon Sep 17 00:00:00 2001 From: Evgeny Vereshchagin Date: Sun, 26 Dec 2021 23:26:56 +0000 Subject: [PATCH 25/41] tests: add fuzz-bcd (cherry picked from commit 4b65fc8725fa169bf870eb022d7b346796977c21) Related: #2013213 --- src/boot/efi/fuzz-bcd.c | 26 ++++++++++++++++++++++++++ src/boot/efi/meson.build | 3 +++ tools/oss-fuzz.sh | 16 ++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 src/boot/efi/fuzz-bcd.c diff --git a/src/boot/efi/fuzz-bcd.c b/src/boot/efi/fuzz-bcd.c new file mode 100644 index 00000000000..e5ed6638a48 --- /dev/null +++ b/src/boot/efi/fuzz-bcd.c @@ -0,0 +1,26 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include "alloc-util.h" +#include "fd-util.h" +#include "fuzz.h" +#include "utf8.h" + +#include "bcd.c" + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + _cleanup_free_ void *p = NULL; + + /* This limit was borrowed from src/boot/efi/boot.c */ + if (size > 100*1024) + return 0; + + if (!getenv("SYSTEMD_LOG_LEVEL")) + log_set_max_level(LOG_CRIT); + + p = memdup(data, size); + assert_se(p); + + char16_t *title = get_bcd_title(p, size); + assert_se(!title || char16_strlen(title) >= 0); + return 0; +} diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build index 16b34f0ac26..229771026dd 100644 --- a/src/boot/efi/meson.build +++ b/src/boot/efi/meson.build @@ -358,6 +358,9 @@ if efi_arch[1] in ['ia32', 'x86_64', 'arm', 'aarch64'] [], 'HAVE_ZSTD'], ] + fuzzers += [ + [['src/boot/efi/fuzz-bcd.c']], + ] endif systemd_boot_objects = [] diff --git a/tools/oss-fuzz.sh b/tools/oss-fuzz.sh index 8a19da665eb..ae57fc25d54 100755 --- a/tools/oss-fuzz.sh +++ b/tools/oss-fuzz.sh @@ -36,6 +36,13 @@ else apt-get install -y gperf m4 gettext python3-pip \ libcap-dev libmount-dev libkmod-dev \ pkg-config wget python3-jinja2 + + # gnu-efi is installed here to enable -Dgnu-efi behind which fuzz-bcd + # is hidden. It isn't linked against efi. It doesn't + # even include "efi.h" because "bcd.c" can work in "unit test" mode + # where it isn't necessary. + apt-get install -y gnu-efi zstd + pip3 install -r .github/workflows/requirements.txt --require-hashes # https://github.com/google/oss-fuzz/issues/6868 @@ -56,6 +63,15 @@ 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" + # The seed corpus is a separate flat archive for each fuzzer, # with a fixed name ${fuzzer}_seed_corpus.zip. for d in "$(dirname "$0")/../test/fuzz/fuzz-"*; do From a528bd7ec209ea7d209a8121e362e6ec9e34d2d1 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Tue, 11 Jan 2022 10:47:01 +0100 Subject: [PATCH 26/41] meson: Use files() for fuzzers Not having to provide the full path in the source tree is much nicer and the produced lists can also be used anywhere in the source tree. (cherry picked from commit bbec46c817951225f1e535d3df95b82a114e502a) Related: #2013213 --- meson.build | 3 ++- src/boot/efi/meson.build | 2 +- src/core/meson.build | 2 +- src/fuzz/meson.build | 20 ++++++++++---------- src/journal-remote/meson.build | 2 +- src/journal/meson.build | 24 ++++++++++++------------ src/libsystemd-network/meson.build | 8 ++++---- src/libsystemd/meson.build | 4 ++-- src/network/meson.build | 4 ++-- src/nspawn/meson.build | 4 ++-- src/resolve/meson.build | 2 +- src/systemctl/meson.build | 7 ++++--- src/udev/meson.build | 11 +++++------ src/xdg-autostart-generator/meson.build | 6 +++--- 14 files changed, 50 insertions(+), 49 deletions(-) diff --git a/meson.build b/meson.build index 35ba29aecfe..fdf02b81101 100644 --- a/meson.build +++ b/meson.build @@ -3677,7 +3677,8 @@ foreach tuple : fuzzers sources += 'src/fuzz/fuzz-main.c' endif - name = sources[0].split('/')[-1].split('.')[0] + # FIXME: Use fs.stem() with meson >= 0.54.0 + name = '@0@'.format(sources[0]).split('/')[-1].split('.')[0] exe = executable( name, diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build index 229771026dd..3e948281f25 100644 --- a/src/boot/efi/meson.build +++ b/src/boot/efi/meson.build @@ -359,7 +359,7 @@ if efi_arch[1] in ['ia32', 'x86_64', 'arm', 'aarch64'] 'HAVE_ZSTD'], ] fuzzers += [ - [['src/boot/efi/fuzz-bcd.c']], + [files('fuzz-bcd.c')], ] endif diff --git a/src/core/meson.build b/src/core/meson.build index d229d46779a..97ac4317637 100644 --- a/src/core/meson.build +++ b/src/core/meson.build @@ -228,7 +228,7 @@ endif ############################################################ fuzzers += [ - [['src/core/fuzz-unit-file.c'], + [files('fuzz-unit-file.c'), [libcore, libshared], [libmount]], diff --git a/src/fuzz/meson.build b/src/fuzz/meson.build index 1ed1dd82518..d987f32b08b 100644 --- a/src/fuzz/meson.build +++ b/src/fuzz/meson.build @@ -1,23 +1,23 @@ # SPDX-License-Identifier: LGPL-2.1-or-later fuzzers += [ - [['src/fuzz/fuzz-catalog.c']], + [files('fuzz-catalog.c')], - [['src/fuzz/fuzz-json.c']], + [files('fuzz-json.c')], - [['src/fuzz/fuzz-varlink.c']], + [files('fuzz-varlink.c')], - [['src/fuzz/fuzz-udev-database.c']], + [files('fuzz-udev-database.c')], - [['src/fuzz/fuzz-compress.c']], + [files('fuzz-compress.c')], - [['src/fuzz/fuzz-bus-label.c']], + [files('fuzz-bus-label.c')], - [['src/fuzz/fuzz-env-file.c']], + [files('fuzz-env-file.c')], - [['src/fuzz/fuzz-hostname-setup.c']], + [files('fuzz-hostname-setup.c')], - [['src/fuzz/fuzz-calendarspec.c']], + [files('fuzz-calendarspec.c')], - [['src/fuzz/fuzz-time-util.c']], + [files('fuzz-time-util.c')], ] diff --git a/src/journal-remote/meson.build b/src/journal-remote/meson.build index 168d0ed6a30..1f3e0878ae6 100644 --- a/src/journal-remote/meson.build +++ b/src/journal-remote/meson.build @@ -76,7 +76,7 @@ endif ############################################################ fuzzers += [ - [['src/journal-remote/fuzz-journal-remote.c'], + [files('fuzz-journal-remote.c'), [libsystemd_journal_remote, libshared], [], diff --git a/src/journal/meson.build b/src/journal/meson.build index b9a63d5e2fe..21c4d2561c5 100644 --- a/src/journal/meson.build +++ b/src/journal/meson.build @@ -116,38 +116,38 @@ tests += [ ] fuzzers += [ - [['src/journal/fuzz-journald-audit.c', - 'src/journal/fuzz-journald.c'], + [files('fuzz-journald-audit.c', + 'fuzz-journald.c'), [libjournal_core, libshared], [libselinux]], - [['src/journal/fuzz-journald-kmsg.c', - 'src/journal/fuzz-journald.c'], + [files('fuzz-journald-kmsg.c', + 'fuzz-journald.c'), [libjournal_core, libshared], [libselinux]], - [['src/journal/fuzz-journald-native.c', - 'src/journal/fuzz-journald.c'], + [files('fuzz-journald-native.c', + 'fuzz-journald.c'), [libjournal_core, libshared], [libselinux]], - [['src/journal/fuzz-journald-native-fd.c', - 'src/journal/fuzz-journald.c'], + [files('fuzz-journald-native-fd.c', + 'fuzz-journald.c'), [libjournal_core, libshared], [libselinux]], - [['src/journal/fuzz-journald-stream.c', - 'src/journal/fuzz-journald.c'], + [files('fuzz-journald-stream.c', + 'fuzz-journald.c'), [libjournal_core, libshared], [libselinux]], - [['src/journal/fuzz-journald-syslog.c', - 'src/journal/fuzz-journald.c'], + [files('fuzz-journald-syslog.c', + 'fuzz-journald.c'), [libjournal_core, libshared], [libselinux]], diff --git a/src/libsystemd-network/meson.build b/src/libsystemd-network/meson.build index 3923df48ea4..6be409d8adb 100644 --- a/src/libsystemd-network/meson.build +++ b/src/libsystemd-network/meson.build @@ -105,19 +105,19 @@ tests += [ ] fuzzers += [ - [['src/libsystemd-network/fuzz-dhcp6-client.c'], + [files('fuzz-dhcp6-client.c'), [libshared, libsystemd_network]], - [['src/libsystemd-network/fuzz-dhcp-server.c'], + [files('fuzz-dhcp-server.c'), [libsystemd_network, libshared]], - [['src/libsystemd-network/fuzz-lldp-rx.c'], + [files('fuzz-lldp-rx.c'), [libshared, libsystemd_network]], - [['src/libsystemd-network/fuzz-ndisc-rs.c'], + [files('fuzz-ndisc-rs.c'), [libshared, libsystemd_network]], ] diff --git a/src/libsystemd/meson.build b/src/libsystemd/meson.build index 42746e560f3..2e5255d4794 100644 --- a/src/libsystemd/meson.build +++ b/src/libsystemd/meson.build @@ -316,7 +316,7 @@ endif ############################################################ fuzzers += [ - [['src/libsystemd/sd-bus/fuzz-bus-message.c']], + [files('sd-bus/fuzz-bus-message.c')], - [['src/libsystemd/sd-bus/fuzz-bus-match.c']], + [files('sd-bus/fuzz-bus-match.c')], ] diff --git a/src/network/meson.build b/src/network/meson.build index a598701e4fe..23743233fa4 100644 --- a/src/network/meson.build +++ b/src/network/meson.build @@ -261,14 +261,14 @@ if conf.get('ENABLE_NETWORKD') == 1 endif fuzzers += [ - [['src/network/fuzz-netdev-parser.c'], + [files('fuzz-netdev-parser.c'), [libnetworkd_core, libsystemd_network, networkd_link_with], [threads], network_includes], - [['src/network/fuzz-network-parser.c'], + [files('fuzz-network-parser.c'), [libnetworkd_core, libsystemd_network, networkd_link_with], diff --git a/src/nspawn/meson.build b/src/nspawn/meson.build index 3c1a9c61827..2934672e9a7 100644 --- a/src/nspawn/meson.build +++ b/src/nspawn/meson.build @@ -66,12 +66,12 @@ tests += [ ] fuzzers += [ - [['src/nspawn/fuzz-nspawn-settings.c'], + [files('fuzz-nspawn-settings.c'), [libshared, libnspawn_core], [libseccomp]], - [['src/nspawn/fuzz-nspawn-oci.c'], + [files('fuzz-nspawn-oci.c'), [libshared, libnspawn_core], [libseccomp]], diff --git a/src/resolve/meson.build b/src/resolve/meson.build index 4de50c3d8e5..1fee993d0a2 100644 --- a/src/resolve/meson.build +++ b/src/resolve/meson.build @@ -216,7 +216,7 @@ tests += [ ] fuzzers += [ - [['src/resolve/fuzz-dns-packet.c'], + [files('fuzz-dns-packet.c'), [libsystemd_resolve_core, libshared], [lib_openssl_or_gcrypt, diff --git a/src/systemctl/meson.build b/src/systemctl/meson.build index 38bf33d49a7..f0d405bb58f 100644 --- a/src/systemctl/meson.build +++ b/src/systemctl/meson.build @@ -83,7 +83,8 @@ else endif fuzzers += [ - [['src/systemctl/fuzz-systemctl-parse-argv.c', - systemctl_sources], + [files('fuzz-systemctl-parse-argv.c') + + systemctl_sources, systemctl_link_with, - [], [], ['-DFUZZ_SYSTEMCTL_PARSE_ARGV']]] + [], [], ['-DFUZZ_SYSTEMCTL_PARSE_ARGV']] +] diff --git a/src/udev/meson.build b/src/udev/meson.build index 57fbf8c8fc0..9fd0bcdd0ef 100644 --- a/src/udev/meson.build +++ b/src/udev/meson.build @@ -174,24 +174,23 @@ if install_sysconfdir endif fuzzers += [ - [['src/udev/net/fuzz-link-parser.c', - 'src/fuzz/fuzz.h'], + [files('net/fuzz-link-parser.c'), [libudevd_core, libshared], [threads, libacl], udev_includes], - [['src/udev/fuzz-udev-rules.c'], + [files('fuzz-udev-rules.c'), [libudevd_core, libshared], [threads, libacl]], - [['src/udev/fuzz-udev-rule-parse-value.c']], + [files('fuzz-udev-rule-parse-value.c')], - [['src/udev/fido_id/fuzz-fido-id-desc.c', - 'src/udev/fido_id/fido_id_desc.c']], + [files('fido_id/fuzz-fido-id-desc.c', + 'fido_id/fido_id_desc.c')], ] tests += [ diff --git a/src/xdg-autostart-generator/meson.build b/src/xdg-autostart-generator/meson.build index 6418f57c40b..cdce66b6fc0 100644 --- a/src/xdg-autostart-generator/meson.build +++ b/src/xdg-autostart-generator/meson.build @@ -12,7 +12,7 @@ tests += [ ] fuzzers += [ - [['src/xdg-autostart-generator/fuzz-xdg-desktop.c', - 'src/xdg-autostart-generator/xdg-autostart-service.c', - 'src/xdg-autostart-generator/xdg-autostart-service.h']], + [files('fuzz-xdg-desktop.c', + 'xdg-autostart-service.c', + 'xdg-autostart-service.h')], ] From e3daea3b9af1bb243bdde17135060aa17ec88567 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Tue, 11 Jan 2022 10:56:22 +0100 Subject: [PATCH 27/41] meson: Add check argument to remaining run_command() calls (cherry picked from commit 68a06b3cdfe35ff08092e139033edb4a5189a439) Related: #2013213 --- man/meson.build | 2 +- src/basic/meson.build | 2 +- src/boot/efi/meson.build | 11 +++++++---- src/test/meson.build | 2 +- test/fuzz/meson.build | 7 ++++--- test/meson.build | 8 +++++--- 6 files changed, 19 insertions(+), 13 deletions(-) diff --git a/man/meson.build b/man/meson.build index a06a6017670..710b4ca0088 100644 --- a/man/meson.build +++ b/man/meson.build @@ -105,7 +105,7 @@ endforeach ############################################################ -have_lxml = run_command(xml_helper_py).returncode() == 0 +have_lxml = run_command(xml_helper_py, check: false).returncode() == 0 if not have_lxml message('python-lxml not available, not making man page indices') endif diff --git a/src/basic/meson.build b/src/basic/meson.build index 229ac97c69a..5a9e13d7417 100644 --- a/src/basic/meson.build +++ b/src/basic/meson.build @@ -384,7 +384,7 @@ filesystem_includes = ['linux/magic.h', 'linux/gfs2_ondisk.h'] check_filesystems = find_program('check-filesystems.sh') -r = run_command([check_filesystems, cpp, 'filesystems-gperf.gperf'] + filesystem_includes) +r = run_command([check_filesystems, cpp, 'filesystems-gperf.gperf'] + filesystem_includes, check: false) if r.returncode() != 0 error('found unknown filesystem(s) defined in kernel headers:\n\n' + r.stdout()) r.stdout() diff --git a/src/boot/efi/meson.build b/src/boot/efi/meson.build index 3e948281f25..fad92f09a1c 100644 --- a/src/boot/efi/meson.build +++ b/src/boot/efi/meson.build @@ -57,8 +57,11 @@ endif efi_libdir = '' foreach dir : [get_option('efi-libdir'), '/usr/lib/gnuefi' / efi_arch[0], - run_command('realpath', '-e', - '/usr/lib' / run_command(cc.cmd_array(), '-print-multi-os-directory').stdout().strip()).stdout().strip()] + run_command( + 'realpath', '-e', + '/usr/lib' / run_command(cc.cmd_array(), '-print-multi-os-directory', check: false).stdout().strip(), + check: false + ).stdout().strip()] if dir != '' and fs.is_dir(dir) efi_libdir = dir break @@ -125,7 +128,7 @@ elif get_option('sbat-distro') != '' value = get_option(sbatvar[0]) if (value == '' or value == 'auto') and not meson.is_cross_build() cmd = 'if [ -e /etc/os-release ]; then . /etc/os-release; else . /usr/lib/os-release; fi; echo $@0@'.format(sbatvar[1]) - value = run_command(sh, '-c', cmd).stdout().strip() + value = run_command(sh, '-c', cmd, check: true).stdout().strip() endif if value == '' error('Required @0@ option not set and autodetection failed'.format(sbatvar[0])) @@ -254,7 +257,7 @@ if efi_arch[1] == 'arm' efi_ldflags += ['-Wl,--no-warn-mismatch'] endif -if run_command('grep', '-q', '__CTOR_LIST__', efi_lds).returncode() == 0 +if run_command('grep', '-q', '__CTOR_LIST__', efi_lds, check: false).returncode() == 0 # fedora has a patched gnu-efi that adds support for ELF constructors. # If ld is called by gcc something about these symbols breaks, resulting # in sd-boot freezing when gnu-efi runs the constructors. Force defining diff --git a/src/test/meson.build b/src/test/meson.build index 9e224d69ce8..75f78e2e1ac 100644 --- a/src/test/meson.build +++ b/src/test/meson.build @@ -11,7 +11,7 @@ test_hashmap_ordered_c = custom_target( test_include_dir = include_directories('.') -path = run_command(sh, '-c', 'echo "$PATH"').stdout().strip() +path = run_command(sh, '-c', 'echo "$PATH"', check: true).stdout().strip() test_env = environment() test_env.set('SYSTEMD_LANGUAGE_FALLBACK_MAP', language_fallback_map) test_env.set('PATH', project_build_root + ':' + path) diff --git a/test/fuzz/meson.build b/test/fuzz/meson.build index 30e26b09cff..b4766de3eb7 100644 --- a/test/fuzz/meson.build +++ b/test/fuzz/meson.build @@ -13,12 +13,13 @@ sanitize_address_undefined = custom_target( sanitizers = [['address,undefined', sanitize_address_undefined]] -if git.found() +if git.found() and fs.exists(project_source_root / '.git') out = run_command(env, '-u', 'GIT_WORK_TREE', git, '--git-dir=@0@/.git'.format(project_source_root), - 'ls-files', ':/test/fuzz/*/*') + 'ls-files', ':/test/fuzz/*/*', + check: true) else - out = run_command(sh, '-c', 'ls @0@/test/fuzz/*/*'.format(project_source_root)) + out = run_command(sh, '-c', 'ls @0@/test/fuzz/*/*'.format(project_source_root), check: true) endif fuzz_regression_tests = [] diff --git a/test/meson.build b/test/meson.build index 04ae9ebc780..baf94703ead 100644 --- a/test/meson.build +++ b/test/meson.build @@ -182,14 +182,16 @@ endif if want_tests != 'false' and dmi_arches.contains(host_machine.cpu_family()) udev_dmi_memory_id_test = find_program('udev-dmi-memory-id-test.sh') - if git.found() + if git.found() and fs.exists(project_source_root / '.git') out = run_command( env, '-u', 'GIT_WORK_TREE', git, '--git-dir=@0@/.git'.format(project_source_root), - 'ls-files', ':/test/dmidecode-dumps/*.bin') + 'ls-files', ':/test/dmidecode-dumps/*.bin', + check: true) else out = run_command( - sh, '-c', 'ls @0@/test/dmidecode-dumps/*.bin'.format(project_source_root)) + sh, '-c', 'ls @0@/test/dmidecode-dumps/*.bin'.format(project_source_root), + check: true) endif foreach p : out.stdout().split() From e9dad7efa81f0a210f049b05fb28c6100a9f1a48 Mon Sep 17 00:00:00 2001 From: Jan Janssen Date: Tue, 11 Jan 2022 11:27:27 +0100 Subject: [PATCH 28/41] meson: Use echo to list files No need to invoke ls when we are just interested in file names. Also, the cd to source root makes the output identical to "git ls-files" (relative instead of absolute paths). (cherry picked from commit 3a469802f4d7b0a59fe1644cb53d34aee4e56bab) Related: #2013213 --- test/fuzz/meson.build | 2 +- test/meson.build | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/test/fuzz/meson.build b/test/fuzz/meson.build index b4766de3eb7..39730a615c6 100644 --- a/test/fuzz/meson.build +++ b/test/fuzz/meson.build @@ -19,7 +19,7 @@ if git.found() and fs.exists(project_source_root / '.git') 'ls-files', ':/test/fuzz/*/*', check: true) else - out = run_command(sh, '-c', 'ls @0@/test/fuzz/*/*'.format(project_source_root), check: true) + out = run_command(sh, '-c', 'cd "@0@"; echo test/fuzz/*/*'.format(project_source_root), check: true) endif fuzz_regression_tests = [] diff --git a/test/meson.build b/test/meson.build index baf94703ead..c5d8d6917ba 100644 --- a/test/meson.build +++ b/test/meson.build @@ -190,7 +190,7 @@ if want_tests != 'false' and dmi_arches.contains(host_machine.cpu_family()) check: true) else out = run_command( - sh, '-c', 'ls @0@/test/dmidecode-dumps/*.bin'.format(project_source_root), + sh, '-c', 'cd "@0@"; echo test/dmidecode-dumps/*.bin'.format(project_source_root), check: true) endif From fad282fdd653498965b9fbbe379cdc2c8b4bf320 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Wed, 2 Feb 2022 15:08:18 +0900 Subject: [PATCH 29/41] test: add a test for mkdir_p() (cherry picked from commit 6f6b017b9bc69df3f3e308c36c95597002ce6e29) Related: #2013213 --- src/test/meson.build | 2 ++ src/test/test-mkdir.c | 30 ++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+) create mode 100644 src/test/test-mkdir.c diff --git a/src/test/meson.build b/src/test/meson.build index 75f78e2e1ac..14b7939b1fb 100644 --- a/src/test/meson.build +++ b/src/test/meson.build @@ -193,6 +193,8 @@ tests += [ [files('test-macro.c')], + [files('test-mkdir.c')], + [files('test-json.c')], [files('test-modhex.c')], diff --git a/src/test/test-mkdir.c b/src/test/test-mkdir.c new file mode 100644 index 00000000000..c715d5f0964 --- /dev/null +++ b/src/test/test-mkdir.c @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ + +#include + +#include "mkdir.h" +#include "path-util.h" +#include "rm-rf.h" +#include "tests.h" +#include "tmpfile-util.h" + +TEST(mkdir_p) { + _cleanup_(rm_rf_physical_and_freep) char *tmp = NULL; + _cleanup_free_ char *p = NULL; + + assert_se(mkdtemp_malloc("/tmp/test-mkdir-XXXXXX", &tmp) >= 0); + + assert_se(p = path_join(tmp, "run")); + assert_se(mkdir_p(p, 0755) >= 0); + + p = mfree(p); + assert_se(p = path_join(tmp, "var/run")); + assert_se(mkdir_parents(p, 0755) >= 0); + assert_se(symlink("../run", p) >= 0); + + p = mfree(p); + assert_se(p = path_join(tmp, "var/run/hoge/foo/baz")); + assert_se(mkdir_p(p, 0755) >= 0); +} + +DEFINE_TEST_MAIN(LOG_DEBUG); From e72d70099144ae205395e6a8e7ef3a2b02f3ffa1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 1 Feb 2022 12:06:21 +0100 Subject: [PATCH 30/41] util: another set of CVE-2021-4034 assert()s It's a good idea that we validate argc/argv when we are supposed to store them away. (cherry picked from commit 007e03b284e8ffc0b92edb2122cd9d2d16f049ef) Related: #2013213 --- src/basic/util.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/basic/util.h b/src/basic/util.h index 94804f28e3f..68ae3b51e0e 100644 --- a/src/basic/util.h +++ b/src/basic/util.h @@ -9,6 +9,12 @@ extern int saved_argc; extern char **saved_argv; static inline void save_argc_argv(int argc, char **argv) { + + /* Protect against CVE-2021-4034 style attacks */ + assert_se(argc > 0); + assert_se(argv); + assert_se(argv[0]); + saved_argc = argc; saved_argv = argv; } From 467e890f128861f2076f39e068bf4dbc565aad70 Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Sun, 30 Jan 2022 23:40:05 +0100 Subject: [PATCH 31/41] basic: update CIFS magic Kernel commit dea2903719283c156b53741126228c4a1b40440f exposed (and renamed) CIFS_MAGIC_NUMBER as CIFS_SUPER_MAGIC along with SMB2_SUPER_MAGIC. This fixes the following build fail on current Fedora Rawhide: ``` ../src/basic/meson.build:389:8: ERROR: Problem encountered: found unknown filesystem(s) defined in kernel headers: Filesystem found in kernel header but not in filesystems-gperf.gperf: CIFS_SUPER_MAGIC Filesystem found in kernel header but not in filesystems-gperf.gperf: SMB2_SUPER_MAGIC ``` (cherry picked from commit bbe53713455be38c0a587626439fd171f28c77fc) Related: #2013213 --- src/basic/filesystems-gperf.gperf | 4 ++-- src/basic/missing_magic.h | 11 ++++++++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/src/basic/filesystems-gperf.gperf b/src/basic/filesystems-gperf.gperf index 08c8c445105..e8c5357f914 100644 --- a/src/basic/filesystems-gperf.gperf +++ b/src/basic/filesystems-gperf.gperf @@ -40,7 +40,7 @@ ceph, {CEPH_SUPER_MAGIC} cgroup2, {CGROUP2_SUPER_MAGIC} # note that the cgroupfs magic got reassigned from cpuset cgroup, {CGROUP_SUPER_MAGIC} -cifs, {CIFS_MAGIC_NUMBER} +cifs, {CIFS_SUPER_MAGIC, SMB2_SUPER_MAGIC} coda, {CODA_SUPER_MAGIC} configfs, {CONFIGFS_MAGIC} cramfs, {CRAMFS_MAGIC} @@ -109,7 +109,7 @@ selinuxfs, {SELINUX_MAGIC} shiftfs, {SHIFTFS_MAGIC} smackfs, {SMACK_MAGIC} # smb3 is an alias for cifs -smb3, {CIFS_MAGIC_NUMBER} +smb3, {CIFS_SUPER_MAGIC} # smbfs was removed from the kernel in 2010, the magic remains smbfs, {SMB_SUPER_MAGIC} sockfs, {SOCKFS_MAGIC} diff --git a/src/basic/missing_magic.h b/src/basic/missing_magic.h index 7d9320bb6dc..c104fcfba31 100644 --- a/src/basic/missing_magic.h +++ b/src/basic/missing_magic.h @@ -38,9 +38,14 @@ #define XFS_SB_MAGIC 0x58465342 #endif -/* Not exposed yet. Defined at fs/cifs/cifsglob.h */ -#ifndef CIFS_MAGIC_NUMBER -#define CIFS_MAGIC_NUMBER 0xFF534D42 +/* dea2903719283c156b53741126228c4a1b40440f (5.17) */ +#ifndef CIFS_SUPER_MAGIC +#define CIFS_SUPER_MAGIC 0xFF534D42 +#endif + +/* dea2903719283c156b53741126228c4a1b40440f (5.17) */ +#ifndef SMB2_SUPER_MAGIC +#define SMB2_SUPER_MAGIC 0xFE534D42 #endif /* 257f871993474e2bde6c497b54022c362cf398e1 (4.5) */ From 32fcbf3cf8eeb33a5181ea8a1d40964ecc1f5884 Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Fri, 28 Jan 2022 21:44:32 +0100 Subject: [PATCH 32/41] shared: be extra paranoid and check if argc > 0 and also if argv[0] is non-empty as a precaution for issues similar to CVE-2021-4034. (cherry picked from commit 1637e757070a61b12b26a2a4ef547330562dc77f) Related: #2013213 --- src/shared/main-func.h | 1 + 1 file changed, 1 insertion(+) diff --git a/src/shared/main-func.h b/src/shared/main-func.h index 05cdffeec00..09103bace96 100644 --- a/src/shared/main-func.h +++ b/src/shared/main-func.h @@ -15,6 +15,7 @@ #define _DEFINE_MAIN_FUNCTION(intro, impl, ret) \ int main(int argc, char *argv[]) { \ int r; \ + assert(argc > 0 && !isempty(argv[0])); \ save_argc_argv(argc, argv); \ intro; \ r = impl; \ From 8b3aef0cadcfde519ced5eb559fe8d1645ca392d Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 30 Jan 2022 17:54:55 +0900 Subject: [PATCH 33/41] core: check if argc > 0 and argv[0] is set Follow-up for 1637e757070a61b12b26a2a4ef547330562dc77f. (cherry picked from commit cf3095ac2bbdba3db0d8f7fa7afcee8b8c136201) Related: #2013213 --- src/core/main.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/core/main.c b/src/core/main.c index 7ea848ebeb4..f315a44a082 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -2726,6 +2726,8 @@ int main(int argc, char *argv[]) { Manager *m = NULL; FDSet *fds = NULL; + assert(argc > 0 && !isempty(argv[0])); + /* SysV compatibility: redirect init → telinit */ redirect_telinit(argc, argv); From c57439915ae2160918db53732db3101cd8d20fd3 Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Sun, 30 Jan 2022 15:49:27 +0100 Subject: [PATCH 34/41] core: check argc/argv uncoditionally as `assert()` might be dropped with `-DNDEBUG`. Follow-up to cf3095a and 1637e75. (cherry picked from commit 61b9769bda465f4832080e2a7a8285d247121d70) Related: #2013213 --- src/core/main.c | 2 +- src/shared/main-func.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/main.c b/src/core/main.c index f315a44a082..cb3131c12a8 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -2726,7 +2726,7 @@ int main(int argc, char *argv[]) { Manager *m = NULL; FDSet *fds = NULL; - assert(argc > 0 && !isempty(argv[0])); + assert_se(argc > 0 && !isempty(argv[0])); /* SysV compatibility: redirect init → telinit */ redirect_telinit(argc, argv); diff --git a/src/shared/main-func.h b/src/shared/main-func.h index 09103bace96..81a5c1813cb 100644 --- a/src/shared/main-func.h +++ b/src/shared/main-func.h @@ -15,7 +15,7 @@ #define _DEFINE_MAIN_FUNCTION(intro, impl, ret) \ int main(int argc, char *argv[]) { \ int r; \ - assert(argc > 0 && !isempty(argv[0])); \ + assert_se(argc > 0 && !isempty(argv[0])); \ save_argc_argv(argc, argv); \ intro; \ r = impl; \ From d8c409bac5e92d73794e39df85051e2ba60b72b2 Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Thu, 27 Jan 2022 22:51:15 +0100 Subject: [PATCH 35/41] test: temporary workaround for #21819 Since the TEST-64-UDEV-STORAGE fails are quite frequent now and the root cause is yet to be discovered, let's add a kludge that attempts to retry the test up to two more times in case it fails, so we don't unnecessarily disturb CIs while the issue is being investigated. Revert this commit once #21819 is sorted out. (cherry picked from commit 95e35511bbdb7810c00c2e4a6cbda5b187192f74) Related: #2013213 --- test/TEST-64-UDEV-STORAGE/test.sh | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/test/TEST-64-UDEV-STORAGE/test.sh b/test/TEST-64-UDEV-STORAGE/test.sh index 0f26eaafeba..f784e659844 100755 --- a/test/TEST-64-UDEV-STORAGE/test.sh +++ b/test/TEST-64-UDEV-STORAGE/test.sh @@ -119,7 +119,6 @@ test_run() { # Execute each currently defined function starting with "testcase_" for testcase in "${TESTCASES[@]}"; do - _image_cleanup echo "------ $testcase: BEGIN ------" # Note for my future frustrated self: `fun && xxx` (as well as ||, if, while, # until, etc.) _DISABLES_ the `set -e` behavior in _ALL_ nested function @@ -130,8 +129,14 @@ test_run() { # So, be careful when adding clean up snippets in the testcase_*() functions - # if the `test_run_one()` function isn't the last command, you have propagate # the exit code correctly (e.g. `test_run_one() || return $?`, see below). - ec=0 - "$testcase" "$test_id" || ec=$? + + # FIXME: temporary workaround for intermittent fails in certain tests + # See: https://github.com/systemd/systemd/issues/21819 + for ((_i = 0; _i < 3; _i++)); do + _image_cleanup + ec=0 + "$testcase" "$test_id" && break || ec=$? + done case $ec in 0) passed+=("$testcase") From 56c7e619d39b7fffb048710ae2d668e1636ee0a6 Mon Sep 17 00:00:00 2001 From: Frantisek Sumsal Date: Thu, 27 Jan 2022 22:50:58 +0100 Subject: [PATCH 36/41] test: don't leak local variable to outer scopes (cherry picked from commit 888d0bc074c6d11593d28c6a876787ae864604ea) Related: #2013213 --- test/TEST-64-UDEV-STORAGE/test.sh | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/test/TEST-64-UDEV-STORAGE/test.sh b/test/TEST-64-UDEV-STORAGE/test.sh index f784e659844..c360c8b6610 100755 --- a/test/TEST-64-UDEV-STORAGE/test.sh +++ b/test/TEST-64-UDEV-STORAGE/test.sh @@ -171,6 +171,7 @@ testcase_megasas2_basic() { return 77 fi + local i local qemu_opts=( "-device megasas-gen2,id=scsi0" "-device megasas-gen2,id=scsi1" @@ -197,6 +198,9 @@ testcase_nvme_basic() { return 77 fi + local i + local qemu_opts=() + for i in {0..27}; do qemu_opts+=( "-device nvme,drive=nvme$i,serial=deadbeef$i,num_queues=8" @@ -220,7 +224,7 @@ testcase_virtio_scsi_identically_named_partitions() { # and attach them to a virtio-scsi controller local qemu_opts=("-device virtio-scsi-pci,id=scsi0,num_queues=4") local diskpath="${TESTDIR:?}/namedpart0.img" - local lodev qemu_timeout + local i lodev qemu_timeout dd if=/dev/zero of="$diskpath" bs=1M count=18 lodev="$(losetup --show -f -P "$diskpath")" @@ -330,7 +334,7 @@ testcase_lvm_basic() { fi local qemu_opts=("-device ahci,id=ahci0") - local diskpath + local diskpath i # Attach 4 SATA disks to the VM (and set their model and serial fields # to something predictable, so we can refer to them later) From c8a106aeeff03e2c1d5d9f7abb65ee6dbe38647d Mon Sep 17 00:00:00 2001 From: Anita Zhang Date: Wed, 26 Jan 2022 10:53:40 -0800 Subject: [PATCH 37/41] tree-wide: don't use strjoina() on getenv() values Avoid doing stack allocations on environment variables. (cherry picked from commit 1d3b68f6e1538b6a86cbe3650d8b81df2877ef42) Related: #2013213 --- src/basic/path-lookup.c | 8 ++++++-- src/core/dbus.c | 8 ++++++-- src/home/homed-home.c | 10 +++++++--- src/home/homed-manager.c | 26 ++++++++++++++++++-------- src/run/run.c | 7 +++++-- src/shared/pager.c | 9 +++++++-- 6 files changed, 49 insertions(+), 19 deletions(-) diff --git a/src/basic/path-lookup.c b/src/basic/path-lookup.c index 6fb8c40e7a5..921a30cef78 100644 --- a/src/basic/path-lookup.c +++ b/src/basic/path-lookup.c @@ -238,7 +238,7 @@ static int acquire_generator_dirs( char **generator_early, char **generator_late) { - _cleanup_free_ char *x = NULL, *y = NULL, *z = NULL; + _cleanup_free_ char *x = NULL, *y = NULL, *z = NULL, *p = NULL; const char *prefix; assert(generator); @@ -261,7 +261,11 @@ static int acquire_generator_dirs( if (!e) return -ENXIO; - prefix = strjoina(e, "/systemd"); + p = path_join(e, "/systemd"); + if (!p) + return -ENOMEM; + + prefix = p; } x = path_join(prefix, "generator"); diff --git a/src/core/dbus.c b/src/core/dbus.c index 2c5bda58f98..073675ceefa 100644 --- a/src/core/dbus.c +++ b/src/core/dbus.c @@ -925,14 +925,18 @@ int bus_init_private(Manager *m) { r = sockaddr_un_set_path(&sa.un, "/run/systemd/private"); } else { - const char *e, *joined; + _cleanup_free_ char *joined = NULL; + const char *e; e = secure_getenv("XDG_RUNTIME_DIR"); if (!e) return log_error_errno(SYNTHETIC_ERRNO(EHOSTDOWN), "XDG_RUNTIME_DIR is not set, refusing."); - joined = strjoina(e, "/systemd/private"); + joined = path_join(e, "/systemd/private"); + if (!joined) + return log_oom(); + r = sockaddr_un_set_path(&sa.un, joined); } if (r < 0) diff --git a/src/home/homed-home.c b/src/home/homed-home.c index 470c7f07f62..1340cf30d33 100644 --- a/src/home/homed-home.c +++ b/src/home/homed-home.c @@ -1185,14 +1185,18 @@ static int home_start_work(Home *h, const char *verb, UserRecord *hr, UserRecord if (r < 0) return r; if (r == 0) { + _cleanup_free_ char *joined = NULL; const char *homework, *suffix, *unix_path; /* Child */ suffix = getenv("SYSTEMD_HOME_DEBUG_SUFFIX"); - if (suffix) - unix_path = strjoina("/run/systemd/home/notify.", suffix); - else + if (suffix) { + joined = strjoin("/run/systemd/home/notify.", suffix); + if (!joined) + return log_oom(); + unix_path = joined; + } else unix_path = "/run/systemd/home/notify"; if (setenv("NOTIFY_SOCKET", unix_path, 1) < 0) { diff --git a/src/home/homed-manager.c b/src/home/homed-manager.c index 6c178b8a0e0..c1ec555cacf 100644 --- a/src/home/homed-manager.c +++ b/src/home/homed-manager.c @@ -936,6 +936,7 @@ int manager_enumerate_images(Manager *m) { } static int manager_connect_bus(Manager *m) { + _cleanup_free_ char *b = NULL; const char *suffix, *busname; int r; @@ -955,9 +956,12 @@ static int manager_connect_bus(Manager *m) { return r; suffix = getenv("SYSTEMD_HOME_DEBUG_SUFFIX"); - if (suffix) - busname = strjoina("org.freedesktop.home1.", suffix); - else + if (suffix) { + b = strjoin("org.freedesktop.home1.", suffix); + if (!b) + return log_oom(); + busname = b; + } else busname = "org.freedesktop.home1"; r = sd_bus_request_name_async(m->bus, NULL, busname, 0, NULL, NULL); @@ -974,6 +978,7 @@ static int manager_connect_bus(Manager *m) { } static int manager_bind_varlink(Manager *m) { + _cleanup_free_ char *p = NULL; const char *suffix, *socket_path; int r; @@ -999,9 +1004,12 @@ static int manager_bind_varlink(Manager *m) { /* To make things easier to debug, when working from a homed managed home directory, let's optionally * use a different varlink socket name */ suffix = getenv("SYSTEMD_HOME_DEBUG_SUFFIX"); - if (suffix) - socket_path = strjoina("/run/systemd/userdb/io.systemd.Home.", suffix); - else + if (suffix) { + p = strjoin("/run/systemd/userdb/io.systemd.Home.", suffix); + if (!p) + return log_oom(); + socket_path = p; + } else socket_path = "/run/systemd/userdb/io.systemd.Home"; r = varlink_server_listen_address(m->varlink_server, socket_path, 0666); @@ -1159,9 +1167,11 @@ static int manager_listen_notify(Manager *m) { suffix = getenv("SYSTEMD_HOME_DEBUG_SUFFIX"); if (suffix) { - const char *unix_path; + _cleanup_free_ char *unix_path = NULL; - unix_path = strjoina("/run/systemd/home/notify.", suffix); + unix_path = strjoin("/run/systemd/home/notify.", suffix); + if (!unix_path) + return log_oom(); r = sockaddr_un_set_path(&sa.un, unix_path); if (r < 0) return log_error_errno(r, "Socket path %s does not fit in sockaddr_un: %m", unix_path); diff --git a/src/run/run.c b/src/run/run.c index ff24373847c..e75b027542f 100644 --- a/src/run/run.c +++ b/src/run/run.c @@ -794,9 +794,12 @@ static int transient_service_set_properties(sd_bus_message *m, const char *pty_p e = getenv("TERM"); if (e) { - char *n; + _cleanup_free_ char *n = NULL; + + n = strjoin("TERM=", e); + if (!n) + return log_oom(); - n = strjoina("TERM=", e); r = sd_bus_message_append(m, "(sv)", "Environment", "as", 1, n); diff --git a/src/shared/pager.c b/src/shared/pager.c index f75ef62d2d0..9426d3ef988 100644 --- a/src/shared/pager.c +++ b/src/shared/pager.c @@ -86,6 +86,7 @@ static int no_quit_on_interrupt(int exe_name_fd, const char *less_opts) { void pager_open(PagerFlags flags) { _cleanup_close_pair_ int fd[2] = { -1, -1 }, exe_name_pipe[2] = { -1, -1 }; _cleanup_strv_free_ char **pager_args = NULL; + _cleanup_free_ char *l = NULL; const char *pager, *less_opts; int r; @@ -131,8 +132,12 @@ void pager_open(PagerFlags flags) { less_opts = getenv("SYSTEMD_LESS"); if (!less_opts) less_opts = "FRSXMK"; - if (flags & PAGER_JUMP_TO_END) - less_opts = strjoina(less_opts, " +G"); + if (flags & PAGER_JUMP_TO_END) { + l = strjoin(less_opts, " +G"); + if (!l) + return (void) log_oom(); + less_opts = l; + } /* We set SIGINT as PR_DEATHSIG signal here, to match the "K" parameter we set in $LESS, which enables SIGINT behaviour. */ r = safe_fork("(pager)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGINT|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pager_pid); From 3007634cd153aca6fca5330804f95b883698debb Mon Sep 17 00:00:00 2001 From: Yonathan Randolph Date: Sun, 26 Dec 2021 17:12:00 -0800 Subject: [PATCH 38/41] man: clarify Environmentfile format Remove incorrect claim that C escapes (such as \t and \n) are recognized and that control characters are disallowed. Specify the allowed characters and escapes with single quotes, with double quotes, and without quotes. (cherry picked from commit 4bbcde8498eb59557ebddd7830efb47c0297ff4b) Related: #2013213 --- man/systemd.exec.xml | 51 ++++++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index cd21d5b28d0..69858d5e59b 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -2485,18 +2485,39 @@ SystemCallErrorNumber=EPERM EnvironmentFile= - Similar to Environment= but reads the environment variables from a text - file. The text file should contain new-line-separated variable assignments. Empty lines, lines without an - = separator, or lines starting with ; or # will be ignored, which may be used for - commenting. A line ending with a backslash will be concatenated with the following one, allowing multiline - variable definitions. The parser strips leading and trailing whitespace from the values of assignments, unless - you use double quotes ("). - - C escapes - are supported, but not - most control characters. - \t and \n can be used to insert tabs and newlines within - EnvironmentFile=. + Similar to Environment= but reads the environment variables from a text file. + The text file should contain newline-separated variable assignments. Empty lines, lines without an + = separator, or lines starting with ; or # will be + ignored, which may be used for commenting. The file must be UTF-8 encoded. Valid characters are unicode scalar values other than noncharacters, U+0000 NUL, and U+FEFF byte order mark. Control codes other than NUL + are allowed. + + In the file, an unquoted value after the = is parsed with the same backslash-escape + rules as unquoted + text in a POSIX shell, but unlike in a shell, interior whitespace is preserved and quotes after the + first non-whitespace character are preserved. Leading and trailing whitespace (space, tab, carriage return) is + discarded, but interior whitespace within the line is preserved verbatim. A line ending with a backslash will be + continued to the following one, with the newline itself discarded. A backslash + \ followed by any character other than newline will preserve the following character, so that + \\ will become the value \. + + In the file, a '-quoted value after the = can span multiple lines + and contain any character verbatim other than single quote, like single-quoted + text in a POSIX shell. No backslash-escape sequences are recognized. Leading and trailing whitespace + outside of the single quotes is discarded. + + In the file, a "-quoted value after the = can span multiple lines, + and the same escape sequences are recognized as in double-quoted + text of a POSIX shell. Backslash (\) followed by any of "\`$ will + preserve that character. A backslash followed by newline is a line continuation, and the newline itself is + discarded. A backslash followed by any other character is ignored; both the backslash and the following + character are preserved verbatim. Leading and trailing whitespace outside of the double quotes is + discarded. The argument passed should be an absolute filename or wildcard expression, optionally prefixed with -, which indicates that if the file does not exist, it will not be read and no error or @@ -2529,12 +2550,6 @@ SystemCallErrorNumber=EPERM Variables set for invoked processes due to this setting are subject to being overridden by those configured with Environment= or EnvironmentFile=. - C escapes - are supported, but not - most control characters. - \t and \n can be used to insert tabs and newlines within - EnvironmentFile=. - Example: PassEnvironment=VAR1 VAR2 VAR3 passes three variables VAR1, From 71d49fc9cd1dd240216cd5fc288e41730ca2659e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 19 Jan 2022 09:39:55 +0100 Subject: [PATCH 39/41] test-load-fragment: add a basic test for config_parse_unit_env_file() (cherry picked from commit 3ef86964ed151aa2464701eef46d665adfd70895) Related: #2013213 --- src/test/test-load-fragment.c | 64 +++++++++++++++++++++++++++++++++++ 1 file changed, 64 insertions(+) diff --git a/src/test/test-load-fragment.c b/src/test/test-load-fragment.c index 1bd68c7e0a4..fbe4744333d 100644 --- a/src/test/test-load-fragment.c +++ b/src/test/test-load-fragment.c @@ -773,6 +773,70 @@ TEST(config_parse_pass_environ) { assert_se(streq(passenv[0], "normal_name")); } +TEST(config_parse_unit_env_file) { + /* int config_parse_unit_env_file( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) */ + + _cleanup_(manager_freep) Manager *m = NULL; + Unit *u; + _cleanup_strv_free_ char **files = NULL; + int r; + + r = manager_new(UNIT_FILE_USER, MANAGER_TEST_RUN_MINIMAL, &m); + if (manager_errno_skip_test(r)) { + log_notice_errno(r, "Skipping test: manager_new: %m"); + return; + } + + assert_se(r >= 0); + assert_se(manager_startup(m, NULL, NULL, NULL) >= 0); + + assert_se(u = unit_new(m, sizeof(Service))); + assert_se(unit_add_name(u, "foobar.service") == 0); + + r = config_parse_unit_env_file(u->id, "fake", 1, "section", 1, + "EnvironmentFile", 0, "not-absolute", + &files, u); + assert_se(r == 0); + assert_se(strv_length(files) == 0); + + r = config_parse_unit_env_file(u->id, "fake", 1, "section", 1, + "EnvironmentFile", 0, "/absolute1", + &files, u); + assert_se(r == 0); + assert_se(strv_length(files) == 1); + + r = config_parse_unit_env_file(u->id, "fake", 1, "section", 1, + "EnvironmentFile", 0, "/absolute2", + &files, u); + assert_se(r == 0); + assert_se(strv_length(files) == 2); + assert_se(streq(files[0], "/absolute1")); + assert_se(streq(files[1], "/absolute2")); + + r = config_parse_unit_env_file(u->id, "fake", 1, "section", 1, + "EnvironmentFile", 0, "", + &files, u); + assert_se(r == 0); + assert_se(strv_isempty(files)); + + r = config_parse_unit_env_file(u->id, "fake", 1, "section", 1, + "EnvironmentFile", 0, "/path/%n.conf", + &files, u); + assert_se(r == 0); + assert_se(strv_length(files) == 1); + assert_se(streq(files[0], "/path/foobar.service.conf")); +} + TEST(unit_dump_config_items) { unit_dump_config_items(stdout); } From e2561163c270a4243d5700f59a6d1a29fdd75d0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 19 Jan 2022 09:51:19 +0100 Subject: [PATCH 40/41] core/execute: use _cleanup_ in exec_context_load_environment() Also rename variables. (cherry picked from commit 398a5009169fdc0c4eb147692c0cd929b9fe4c84) Related: #2013213 --- src/core/execute.c | 51 +++++++++++++++++++--------------------------- 1 file changed, 21 insertions(+), 30 deletions(-) diff --git a/src/core/execute.c b/src/core/execute.c index 16f346f3396..2ab65e9cfef 100644 --- a/src/core/execute.c +++ b/src/core/execute.c @@ -5363,20 +5363,18 @@ static int exec_context_named_iofds( return targets == 0 ? 0 : -ENOENT; } -static int exec_context_load_environment(const Unit *unit, const ExecContext *c, char ***l) { - char **i, **r = NULL; +static int exec_context_load_environment(const Unit *unit, const ExecContext *c, char ***ret) { + _cleanup_strv_free_ char **v = NULL; + char **i; + int r; assert(c); - assert(l); + assert(ret); STRV_FOREACH(i, c->environment_files) { - char *fn; - int k; - bool ignore = false; - char **p; _cleanup_globfree_ glob_t pglob = {}; - - fn = *i; + bool ignore = false; + char *fn = *i; if (fn[0] == '-') { ignore = true; @@ -5386,33 +5384,30 @@ static int exec_context_load_environment(const Unit *unit, const ExecContext *c, if (!path_is_absolute(fn)) { if (ignore) continue; - - strv_free(r); return -EINVAL; } /* Filename supports globbing, take all matching files */ - k = safe_glob(fn, 0, &pglob); - if (k < 0) { + r = safe_glob(fn, 0, &pglob); + if (r < 0) { if (ignore) continue; - - strv_free(r); - return k; + return r; } /* When we don't match anything, -ENOENT should be returned */ assert(pglob.gl_pathc > 0); for (unsigned n = 0; n < pglob.gl_pathc; n++) { - k = load_env_file(NULL, pglob.gl_pathv[n], &p); - if (k < 0) { + _cleanup_strv_free_ char **p = NULL; + + r = load_env_file(NULL, pglob.gl_pathv[n], &p); + if (r < 0) { if (ignore) continue; - - strv_free(r); - return k; + return r; } + /* Log invalid environment variables with filename */ if (p) { InvalidEnvInfo info = { @@ -5423,23 +5418,19 @@ static int exec_context_load_environment(const Unit *unit, const ExecContext *c, p = strv_env_clean_with_callback(p, invalid_env, &info); } - if (!r) - r = p; + if (!v) + v = TAKE_PTR(p); else { - char **m; - - m = strv_env_merge(r, p); - strv_free(r); - strv_free(p); + char **m = strv_env_merge(v, p); if (!m) return -ENOMEM; - r = m; + strv_free_and_replace(v, m); } } } - *l = r; + *ret = TAKE_PTR(v); return 0; } From b413585527c762eb4cc5e5d74b00c9c37f18a617 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Wed, 19 Jan 2022 10:15:50 +0100 Subject: [PATCH 41/41] test-env-file: add tests for quoting in env files (cherry picked from commit e9e982a29d52834375e5fb553cecb45bc905cf91) Related: #2013213 --- src/test/test-env-file.c | 68 +++++++++++++++++++++++++++++----------- 1 file changed, 50 insertions(+), 18 deletions(-) diff --git a/src/test/test-env-file.c b/src/test/test-env-file.c index 6cc2455c1f2..7b132447bf3 100644 --- a/src/test/test-env-file.c +++ b/src/test/test-env-file.c @@ -13,11 +13,11 @@ "a=a\n" \ "b=b\\\n" \ "c\n" \ - "d=d\\\n" \ - "e\\\n" \ - "f\n" \ + "d= d\\\n" \ + "e \\\n" \ + "f \n" \ "g=g\\ \n" \ - "h=h\n" \ + "h= ąęół\\ śćńźżµ \n" \ "i=i\\" #define env_file_2 \ @@ -26,22 +26,34 @@ #define env_file_3 \ "#SPAMD_ARGS=\"-d --socketpath=/var/lib/bulwark/spamd \\\n" \ "#--nouser-config \\\n" \ - "normal=line" - -#define env_file_4 \ - "# Generated\n" \ - "\n" \ - "HWMON_MODULES=\"coretemp f71882fg\"\n" \ - "\n" \ - "# For compatibility reasons\n" \ - "\n" \ - "MODULE_0=coretemp\n" \ - "MODULE_1=f71882fg" + "normal=line \\\n" \ + ";normal=ignored \\\n" \ + "normal_ignored \\\n" \ + "normal ignored \\\n" + +#define env_file_4 \ + "# Generated\n" \ + "\n" \ + "HWMON_MODULES=\"coretemp f71882fg\"\n" \ + "\n" \ + "# For compatibility reasons\n" \ + "\n" \ + "MODULE_0=coretemp\n" \ + "MODULE_1=f71882fg" #define env_file_5 \ - "a=\n" \ + "a=\n" \ "b=" +#define env_file_6 \ + "a=\\ \\n \\t \\x \\y \\' \n" \ + "b= \\$' \n" \ + "c= ' \\n\\t\\$\\`\\\\\n" \ + "' \n" \ + "d= \" \\n\\t\\$\\`\\\\\n" \ + "\" \n" + + TEST(load_env_file_1) { _cleanup_strv_free_ char **data = NULL; int r; @@ -57,9 +69,9 @@ TEST(load_env_file_1) { assert_se(r == 0); assert_se(streq(data[0], "a=a")); assert_se(streq(data[1], "b=bc")); - assert_se(streq(data[2], "d=def")); + assert_se(streq(data[2], "d=de f")); assert_se(streq(data[3], "g=g ")); - assert_se(streq(data[4], "h=h")); + assert_se(streq(data[4], "h=ąęół śćńźżµ")); assert_se(streq(data[5], "i=i")); assert_se(data[6] == NULL); } @@ -133,6 +145,26 @@ TEST(load_env_file_5) { assert_se(data[2] == NULL); } +TEST(load_env_file_6) { + _cleanup_strv_free_ char **data = NULL; + int r; + + _cleanup_(unlink_tempfilep) char name[] = "/tmp/test-load-env-file.XXXXXX"; + _cleanup_close_ int fd; + + fd = mkostemp_safe(name); + assert_se(fd >= 0); + assert_se(write(fd, env_file_6, strlen(env_file_6)) == strlen(env_file_6)); + + r = load_env_file(NULL, name, &data); + assert_se(r == 0); + assert_se(streq(data[0], "a= n t x y '")); + assert_se(streq(data[1], "b=$'")); + assert_se(streq(data[2], "c= \\n\\t\\$\\`\\\\\n")); + assert_se(streq(data[3], "d= \\n\\t$`\\\n")); + assert_se(data[4] == NULL); +} + TEST(write_and_load_env_file) { const char *v;