Version in base suite: 252.22-1~deb12u1 Base version: systemd_252.22-1~deb12u1 Target version: systemd_252.23-1~deb12u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/s/systemd/systemd_252.22-1~deb12u1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/s/systemd/systemd_252.23-1~deb12u1.dsc .github/workflows/unit_tests.sh | 3 .semaphore/semaphore-runner.sh | 2 debian/changelog | 7 debian/patches/debian/Downgrade-a-couple-of-warnings-to-debug.patch | 4 debian/patches/debian/fsckd-daemon-for-inter-fsckd-communication.patch | 2 debian/patches/p11kit-switch-to-dlopen.patch | 8 docs/UIDS-GIDS.md | 32 +-- man/machine-id.xml | 3 man/org.freedesktop.portable1.xml | 7 man/org.freedesktop.systemd1.xml | 8 man/systemd-nspawn.xml | 3 man/systemd.exec.xml | 6 man/systemd.service.xml | 77 ++----- man/udev.xml | 15 - meson.build | 2 src/basic/architecture.c | 2 src/basic/cgroup-util.h | 5 src/basic/fd-util.c | 4 src/basic/fs-util.c | 8 src/basic/missing_syscall.h | 19 - src/basic/missing_syscall_def.h | 102 ++++++++-- src/basic/missing_syscalls.py | 3 src/basic/string-util.c | 12 + src/basic/string-util.h | 5 src/basic/strv.h | 12 - src/basic/user-util.c | 2 src/basic/virt.c | 13 - src/core/dbus-cgroup.c | 2 src/core/dbus-execute.c | 4 src/core/execute.c | 12 + src/core/kmod-setup.c | 36 ++- src/core/load-fragment.c | 2 src/core/service.c | 3 src/libsystemd/sd-bus/bus-socket.c | 22 +- src/libsystemd/sd-bus/sd-bus.c | 18 + src/libsystemd/sd-bus/test-bus-watch-bind.c | 9 src/libsystemd/sd-id128/id128-util.c | 2 src/login/user-runtime-dir.c | 2 src/machine/machinectl.c | 2 src/network/wait-online/manager.c | 4 src/nspawn/nspawn.c | 6 src/portable/portablectl.c | 2 src/resolve/resolved-dns-dnssec.c | 21 +- src/resolve/resolved-dns-dnssec.h | 9 src/resolve/resolved-dns-transaction.c | 19 + src/shared/base-filesystem.c | 2 src/shared/bus-unit-util.c | 6 src/shared/conf-parser.c | 2 src/shared/efi-loader.c | 11 - src/shared/generate-syscall-list.py | 9 src/shared/keyring-util.c | 21 -- src/shared/loop-util.c | 2 src/shared/machine-id-setup.c | 2 src/shared/seccomp-util.c | 25 ++ src/shared/utmp-wtmp.c | 1 src/systemd/sd-gpt.h | 2 src/sysusers/sysusers.c | 8 src/test/test-calendarspec.c | 9 src/test/test-date.c | 3 src/test/test-execute.c | 2 src/test/test-fs-util.c | 38 +++ src/test/test-namespace.c | 2 src/test/test-nss-hosts.c | 6 src/test/test-seccomp.c | 28 ++ src/test/test-time-util.c | 3 src/timesync/timesyncd-manager.c | 35 +-- src/timesync/timesyncd-manager.h | 1 src/tmpfiles/tmpfiles.c | 8 test/TEST-24-CRYPTSETUP/test.sh | 7 test/TEST-55-OOMD/test.sh | 13 - test/knot-data/knot.conf | 2 test/test-functions | 12 - test/test-shutdown.py | 5 test/test-sysusers.sh.in | 2 test/units/testsuite-23.utmp.sh | 22 ++ test/units/testsuite-43.sh | 5 test/units/testsuite-55.sh | 68 ++---- 77 files changed, 588 insertions(+), 315 deletions(-) diff: /srv/release.debian.org/tmp/QKewKQTVeN/systemd-252.22/test/testdata: recursive directory loop diff -Nru systemd-252.22/.github/workflows/unit_tests.sh systemd-252.23/.github/workflows/unit_tests.sh --- systemd-252.22/.github/workflows/unit_tests.sh 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/.github/workflows/unit_tests.sh 2024-02-28 16:57:11.000000000 +0000 @@ -76,7 +76,8 @@ MESON_ARGS+=(--fatal-meson-warnings) run_meson -Dnobody-group=nogroup --werror -Dtests=unsafe -Dslow-tests=true -Dfuzz-tests=true "${MESON_ARGS[@]}" build ninja -C build -v - meson test -C build --print-errorlogs + # Ensure setting a timezone (like the reproducible build tests do) does not break time/date unit tests + TZ=GMT+12 meson test -C build --print-errorlogs ;; RUN_ASAN_UBSAN|RUN_GCC_ASAN_UBSAN|RUN_CLANG_ASAN_UBSAN|RUN_CLANG_ASAN_UBSAN_NO_DEPS) MESON_ARGS=(--optimization=1) diff -Nru systemd-252.22/.semaphore/semaphore-runner.sh systemd-252.23/.semaphore/semaphore-runner.sh --- systemd-252.22/.semaphore/semaphore-runner.sh 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/.semaphore/semaphore-runner.sh 2024-02-28 16:57:11.000000000 +0000 @@ -63,7 +63,7 @@ sudo apt-get install -y -t "$UBUNTU_RELEASE-backports" lxc sudo apt-get install -y python3-debian git dpkg-dev fakeroot python3-jinja2 - [ -d "$AUTOPKGTEST_DIR" ] || git clone --quiet --depth=1 https://salsa.debian.org/ci-team/autopkgtest.git "$AUTOPKGTEST_DIR" + [ -d "$AUTOPKGTEST_DIR" ] || git clone --quiet --branch=debian/5.32 --depth=1 https://salsa.debian.org/ci-team/autopkgtest.git "$AUTOPKGTEST_DIR" create_container ;; diff -Nru systemd-252.22/debian/changelog systemd-252.23/debian/changelog --- systemd-252.22/debian/changelog 2024-01-26 21:48:36.000000000 +0000 +++ systemd-252.23/debian/changelog 2024-02-28 17:00:53.000000000 +0000 @@ -1,3 +1,10 @@ +systemd (252.23-1~deb12u1) bookworm; urgency=medium + + * New upstream version 252.23 (CVE-2023-50387, CVE-2023-50868) + * Refresh patches + + -- Luca Boccassi Wed, 28 Feb 2024 17:00:53 +0000 + systemd (252.22-1~deb12u1) bookworm; urgency=medium * d/t/control: add dependency on stress for upstream suite. Needed by diff -Nru systemd-252.22/debian/patches/debian/Downgrade-a-couple-of-warnings-to-debug.patch systemd-252.23/debian/patches/debian/Downgrade-a-couple-of-warnings-to-debug.patch --- systemd-252.22/debian/patches/debian/Downgrade-a-couple-of-warnings-to-debug.patch 2024-01-26 21:48:26.000000000 +0000 +++ systemd-252.23/debian/patches/debian/Downgrade-a-couple-of-warnings-to-debug.patch 2024-02-28 17:00:53.000000000 +0000 @@ -16,7 +16,7 @@ 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c -index 1001faa..555492e 100644 +index 5f4d4b0..cf5e55f 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -543,6 +543,7 @@ static int patch_var_run( @@ -51,7 +51,7 @@ "Please update package to include a native systemd unit file, in order to make it more safe and robust.", fpath); diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c -index 9c3d994..15180a5 100644 +index 281284c..8952a26 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -2991,6 +2991,7 @@ static int specifier_expansion_from_arg(const Specifier *specifier_table, Item * diff -Nru systemd-252.22/debian/patches/debian/fsckd-daemon-for-inter-fsckd-communication.patch systemd-252.23/debian/patches/debian/fsckd-daemon-for-inter-fsckd-communication.patch --- systemd-252.22/debian/patches/debian/fsckd-daemon-for-inter-fsckd-communication.patch 2024-01-26 21:48:26.000000000 +0000 +++ systemd-252.23/debian/patches/debian/fsckd-daemon-for-inter-fsckd-communication.patch 2024-02-28 17:00:53.000000000 +0000 @@ -239,7 +239,7 @@ + + diff --git a/meson.build b/meson.build -index 27d95e7..9ace3e6 100644 +index e707742..6330645 100644 --- a/meson.build +++ b/meson.build @@ -3368,6 +3368,15 @@ executable( diff -Nru systemd-252.22/debian/patches/p11kit-switch-to-dlopen.patch systemd-252.23/debian/patches/p11kit-switch-to-dlopen.patch --- systemd-252.22/debian/patches/p11kit-switch-to-dlopen.patch 2024-01-26 21:48:26.000000000 +0000 +++ systemd-252.23/debian/patches/p11kit-switch-to-dlopen.patch 2024-02-28 17:00:53.000000000 +0000 @@ -13,7 +13,7 @@ 7 files changed, 202 insertions(+), 60 deletions(-) diff --git a/meson.build b/meson.build -index 9de2309..27d95e7 100644 +index afcb4a7..e707742 100644 --- a/meson.build +++ b/meson.build @@ -1462,8 +1462,10 @@ if want_p11kit != 'false' and not skip_deps @@ -718,10 +718,10 @@ } diff --git a/test/test-functions b/test/test-functions -index 73fbef8..0ba7ce2 100644 +index da17bff..58257d4 100644 --- a/test/test-functions +++ b/test/test-functions -@@ -1386,7 +1386,7 @@ install_missing_libraries() { +@@ -1391,7 +1391,7 @@ install_missing_libraries() { local lib path # A number of dependencies is now optional via dlopen, so the install # script will not pick them up, since it looks at linkage. @@ -730,7 +730,7 @@ ddebug "Searching for $lib via pkg-config" if pkg-config --exists "$lib"; then path="$(pkg-config --variable=libdir "$lib")" -@@ -1398,6 +1398,10 @@ install_missing_libraries() { +@@ -1403,6 +1403,10 @@ install_missing_libraries() { if ! [[ ${lib} =~ ^lib ]]; then lib="lib${lib}" fi diff -Nru systemd-252.22/docs/UIDS-GIDS.md systemd-252.23/docs/UIDS-GIDS.md --- systemd-252.22/docs/UIDS-GIDS.md 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/docs/UIDS-GIDS.md 2024-02-28 16:57:11.000000000 +0000 @@ -21,7 +21,7 @@ In theory, the range of the C type `uid_t` is 32bit wide on Linux, i.e. 0…4294967295. However, four UIDs are special on Linux: -1. 0 → The `root` super-user +1. 0 → The `root` super-user. 2. 65534 → The `nobody` UID, also called the "overflow" UID or similar. It's where various subsystems map unmappable users to, for example file systems @@ -57,20 +57,20 @@ 2. 1000…65533 and 65536…4294967294 → Everything else, i.e. regular (human) users. -Note that most distributions allow changing the boundary between system and -regular users, even during runtime as user configuration. Moreover, some older -systems placed the boundary at 499/500, or even 99/100. In `systemd`, the -boundary is configurable only during compilation time, as this should be a -decision for distribution builders, not for users. Moreover, we strongly -discourage downstreams to change the boundary from the upstream default of -999/1000. +Some older systems placed the boundary at 499/500, or even 99/100, +and some distributions allow the boundary between system and regular users to be changed +via local configuration. +In `systemd`, the boundary is configurable during compilation time +and is also queried from `/etc/login.defs` at runtime, +if the `-Dcompat-mutable-uid-boundaries=true` compile-time setting is used. +We strongly discourage downstreams from changing the boundary from the upstream default of 999/1000. Also note that programs such as `adduser` tend to allocate from a subset of the -available regular user range only, usually 1000..60000. And it's also usually -user-configurable, too. +available regular user range only, usually 1000..60000. +This range can also be configured using `/etc/login.defs`. Note that systemd requires that system users and groups are resolvable without -networking available — a requirement that is not made for regular users. This +network — a requirement that is not made for regular users. This means regular users may be stored in remote LDAP or NIS databases, but system users may not (except when there's a consistent local cache kept, that is available during earliest boot, including in the initrd). @@ -155,15 +155,15 @@ `pkg-config`: ``` -$ pkg-config --variable=systemuidmax systemd +$ pkg-config --variable=system_uid_max systemd 999 -$ pkg-config --variable=dynamicuidmin systemd +$ pkg-config --variable=dynamic_uid_min systemd 61184 -$ pkg-config --variable=dynamicuidmax systemd +$ pkg-config --variable=dynamic_uid_max systemd 65519 -$ pkg-config --variable=containeruidbasemin systemd +$ pkg-config --variable=container_uid_base_min systemd 524288 -$ pkg-config --variable=containeruidbasemax systemd +$ pkg-config --variable=container_uid_base_max systemd 1878982656 ``` diff -Nru systemd-252.22/man/machine-id.xml systemd-252.23/man/machine-id.xml --- systemd-252.22/man/machine-id.xml 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/man/machine-id.xml 2024-02-28 16:57:11.000000000 +0000 @@ -101,7 +101,8 @@ to use the D-Bus machine ID from /var/lib/dbus/machine-id, the value of the kernel command line option container_uuid, the KVM DMI product_uuid or the devicetree vm,uuid - (on KVM systems), and finally a randomly generated UUID. + (on KVM systems), the Xen hypervisor uuid, and finally a randomly + generated UUID. After the machine ID is established, systemd1 diff -Nru systemd-252.22/man/org.freedesktop.portable1.xml systemd-252.23/man/org.freedesktop.portable1.xml --- systemd-252.22/man/org.freedesktop.portable1.xml 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/man/org.freedesktop.portable1.xml 2024-02-28 16:57:11.000000000 +0000 @@ -249,7 +249,8 @@ mkdir Note that an image cannot be attached if a unit that it contains is already present - on the system. + on the system. Note that this method returns only after all the listed operations are completed, + and due to the I/O involved it might take some time. AttachImageWithExtensions() attaches a portable image to the system. This method is a superset of AttachImage() with the addition of @@ -271,7 +272,9 @@ unlink - Note that an image cannot be detached if a unit that it contains is running. + Note that an image cannot be detached if a unit that it contains is running. Note that this method + returns only after all the listed operations are completed, and due to the I/O involved it might take + some time. DetachImageWithExtensions() detaches a portable image from the system. This method is a superset of DetachImage() with the addition of diff -Nru systemd-252.22/man/org.freedesktop.systemd1.xml systemd-252.23/man/org.freedesktop.systemd1.xml --- systemd-252.22/man/org.freedesktop.systemd1.xml 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/man/org.freedesktop.systemd1.xml 2024-02-28 16:57:11.000000000 +0000 @@ -1228,7 +1228,13 @@ and terminate all units that aren't dependencies of it. If ignore-dependencies, it will start a unit but ignore all its dependencies. If ignore-requirements, it will start a unit but only ignore the requirement dependencies. It is not recommended to make use of the - latter two options. On completion, this method returns the newly created job object. + latter two options. On reply, if successful, this method returns the newly created job object + which has been enqueued for asynchronous activation. Callers that want to track the outcome of the + actual start operation need to monitor the result of this job. This can be achieved in a race-free + manner by first subscribing to the JobRemoved() signal, then calling + StartUnit() and using the returned job object to filter out unrelated + JobRemoved() signals, until the desired one is received, which will then carry + the result of the start operation. StartUnitReplace() is similar to StartUnit() but replaces a job that is queued for one unit by a job for another unit. diff -Nru systemd-252.22/man/systemd-nspawn.xml systemd-252.23/man/systemd-nspawn.xml --- systemd-252.22/man/systemd-nspawn.xml 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/man/systemd-nspawn.xml 2024-02-28 16:57:11.000000000 +0000 @@ -1317,7 +1317,8 @@ and the subdirectory is symlinked into the host at the same location. try-host and try-guest do the same but do not fail if - the host does not have persistent journaling enabled. If + the host does not have persistent journaling enabled, or if + the container is in the mode. If auto (the default), and the right subdirectory of /var/log/journal exists, it will be bind mounted into the container. If the diff -Nru systemd-252.22/man/systemd.exec.xml systemd-252.23/man/systemd.exec.xml --- systemd-252.22/man/systemd.exec.xml 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/man/systemd.exec.xml 2024-02-28 16:57:11.000000000 +0000 @@ -1101,9 +1101,9 @@ IgnoreSIGPIPE= - Takes a boolean argument. If true, causes SIGPIPE to be ignored in the - executed process. Defaults to true because SIGPIPE generally is useful only in shell - pipelines. + Takes a boolean argument. If true, SIGPIPE is ignored in the + executed process. Defaults to true since SIGPIPE is generally only useful in + shell pipelines. diff -Nru systemd-252.22/man/systemd.service.xml systemd-252.23/man/systemd.service.xml --- systemd-252.22/man/systemd.service.xml 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/man/systemd.service.xml 2024-02-28 16:57:11.000000000 +0000 @@ -765,62 +765,41 @@ Restart= - Configures whether the service shall be - restarted when the service process exits, is killed, or a - timeout is reached. The service process may be the main - service process, but it may also be one of the processes - specified with ExecStartPre=, - ExecStartPost=, - ExecStop=, - ExecStopPost=, or - ExecReload=. When the death of the process - is a result of systemd operation (e.g. service stop or - restart), the service will not be restarted. Timeouts include - missing the watchdog "keep-alive ping" deadline and a service - start, reload, and stop operation timeouts. + Configures whether the service shall be restarted when the service process exits, + is killed, or a timeout is reached. The service process may be the main service process, but it may + also be one of the processes specified with ExecStartPre=, + ExecStartPost=, ExecStop=, ExecStopPost=, + or ExecReload=. When the death of the process is a result of systemd operation + (e.g. service stop or restart), the service will not be restarted. Timeouts include missing the watchdog + "keep-alive ping" deadline and a service start, reload, and stop operation timeouts. - Takes one of - , - , - , - , - , - , or - . - If set to (the default), the service will - not be restarted. If set to , it - will be restarted only when the service process exits cleanly. + Takes one of , , , + , , , or + . If set to (the default), the service will not be restarted. + If set to , it will be restarted only when the service process exits cleanly. In this context, a clean exit means any of the following: exit code of 0; - for types other than - Type=oneshot, one of the signals - SIGHUP, - SIGINT, - SIGTERM, or - SIGPIPE; + for types other than Type=oneshot, one of the signals + SIGHUP, SIGINT, + SIGTERM, or SIGPIPE; + exit statuses and signals specified in SuccessExitStatus=. - If set to - , the service will be restarted - when the process exits with a non-zero exit code, is - terminated by a signal (including on core dump, but excluding - the aforementioned four signals), when an operation (such as - service reload) times out, and when the configured watchdog - timeout is triggered. If set to , - the service will be restarted when the process is terminated - by a signal (including on core dump, excluding the - aforementioned four signals), when an operation times out, or - when the watchdog timeout is triggered. If set to - , the service will be restarted only - if the service process exits due to an uncaught signal not - specified as a clean exit status. If set to - , the service will be restarted - only if the watchdog timeout for the service expires. If set - to , the service will be restarted - regardless of whether it exited cleanly or not, got terminated - abnormally by a signal, or hit a timeout. + If set to , the service will be restarted when the process exits with + a non-zero exit code, is terminated by a signal (including on core dump, but excluding the aforementioned + four signals), when an operation (such as service reload) times out, and when the configured watchdog + timeout is triggered. If set to , the service will be restarted when + the process is terminated by a signal (including on core dump, excluding the aforementioned four signals), + when an operation times out, or when the watchdog timeout is triggered. If set to , + the service will be restarted only if the service process exits due to an uncaught signal not specified + as a clean exit status. If set to , the service will be restarted + only if the watchdog timeout for the service expires. If set to , the service + will be restarted regardless of whether it exited cleanly or not, got terminated abnormally by + a signal, or hit a timeout. Note that Type=oneshot services will never be restarted + on a clean exit status, i.e. and are rejected + for them. Exit causes and the effect of the <varname>Restart=</varname> settings diff -Nru systemd-252.22/man/udev.xml systemd-252.23/man/udev.xml --- systemd-252.22/man/udev.xml 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/man/udev.xml 2024-02-28 16:57:11.000000000 +0000 @@ -680,15 +680,16 @@ - The NAME, SYMLINK, - PROGRAM, OWNER, - GROUP, MODE, SECLABEL, - and RUN fields support simple string substitutions. + The ENV, GROUP, + MODE, NAME, + OWNER, PROGRAM, + RUN, SECLABEL, and + SYMLINK fields support simple string substitutions. The RUN substitutions are performed after all rules have been processed, right before the program is executed, allowing for - the use of device properties set by earlier matching rules. For all other - fields, substitutions are performed while the individual rule is being - processed. The available substitutions are: + the use of device properties set by earlier matching rules. For all + other fields, substitutions are performed while the individual rule is + being processed. The available substitutions are: , diff -Nru systemd-252.22/meson.build systemd-252.23/meson.build --- systemd-252.22/meson.build 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/meson.build 2024-02-28 16:57:11.000000000 +0000 @@ -321,7 +321,7 @@ want_tests = get_option('tests') slow_tests = want_tests != 'false' and get_option('slow-tests') fuzz_tests = want_tests != 'false' and get_option('fuzz-tests') -install_tests = get_option('install-tests') +install_tests = want_tests != 'false' and get_option('install-tests') if add_languages('cpp', required : fuzzer_build) # Used only for tests diff -Nru systemd-252.22/src/basic/architecture.c systemd-252.23/src/basic/architecture.c --- systemd-252.22/src/basic/architecture.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/basic/architecture.c 2024-02-28 16:57:11.000000000 +0000 @@ -70,7 +70,7 @@ { "parisc64", ARCHITECTURE_PARISC64 }, { "parisc", ARCHITECTURE_PARISC }, -#elif defined(__loongarch64) +#elif defined(__loongarch_lp64) { "loongarch64", ARCHITECTURE_LOONGARCH64 }, #elif defined(__m68k__) diff -Nru systemd-252.22/src/basic/cgroup-util.h systemd-252.23/src/basic/cgroup-util.h --- systemd-252.22/src/basic/cgroup-util.h 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/basic/cgroup-util.h 2024-02-28 16:57:11.000000000 +0000 @@ -66,10 +66,13 @@ /* All real cgroup v2 controllers */ CGROUP_MASK_V2 = CGROUP_MASK_CPU|CGROUP_MASK_CPUSET|CGROUP_MASK_IO|CGROUP_MASK_MEMORY|CGROUP_MASK_PIDS, + /* All controllers we want to delegate in case of Delegate=yes. Which are prety much the v2 controllers only, as delegation on v1 is not safe, and bpf stuff isn't a real controller */ + CGROUP_MASK_DELEGATE = CGROUP_MASK_V2, + /* All cgroup v2 BPF pseudo-controllers */ CGROUP_MASK_BPF = CGROUP_MASK_BPF_FIREWALL|CGROUP_MASK_BPF_DEVICES|CGROUP_MASK_BPF_FOREIGN|CGROUP_MASK_BPF_SOCKET_BIND|CGROUP_MASK_BPF_RESTRICT_NETWORK_INTERFACES, - _CGROUP_MASK_ALL = CGROUP_CONTROLLER_TO_MASK(_CGROUP_CONTROLLER_MAX) - 1 + _CGROUP_MASK_ALL = CGROUP_CONTROLLER_TO_MASK(_CGROUP_CONTROLLER_MAX) - 1, } CGroupMask; static inline CGroupMask CGROUP_MASK_EXTEND_JOINED(CGroupMask mask) { diff -Nru systemd-252.22/src/basic/fd-util.c systemd-252.23/src/basic/fd-util.c --- systemd-252.22/src/basic/fd-util.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/basic/fd-util.c 2024-02-28 16:57:11.000000000 +0000 @@ -284,7 +284,7 @@ case 0: /* Close everything. Yay! */ - if (close_range(3, -1, 0) >= 0) + if (close_range(3, INT_MAX, 0) >= 0) return 1; if (ERRNO_IS_NOT_SUPPORTED(errno) || ERRNO_IS_PRIVILEGE(errno)) { @@ -395,7 +395,7 @@ if (sorted[n_sorted-1] >= INT_MAX) /* Dont let the addition below overflow */ return 0; - if (close_range(sorted[n_sorted-1] + 1, -1, 0) >= 0) + if (close_range(sorted[n_sorted-1] + 1, INT_MAX, 0) >= 0) return 0; if (!ERRNO_IS_NOT_SUPPORTED(errno) && !ERRNO_IS_PRIVILEGE(errno)) diff -Nru systemd-252.22/src/basic/fs-util.c systemd-252.23/src/basic/fs-util.c --- systemd-252.22/src/basic/fs-util.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/basic/fs-util.c 2024-02-28 16:57:11.000000000 +0000 @@ -118,7 +118,11 @@ int readlinkat_malloc(int fd, const char *p, char **ret) { size_t l = PATH_MAX; - assert(p); + assert(fd >= 0 || fd == AT_FDCWD); + + if (fd < 0 && isempty(p)) + return -EISDIR; /* In this case, the fd points to the current working directory, and is + * definitely not a symlink. Let's return earlier. */ for (;;) { _cleanup_free_ char *c = NULL; @@ -128,7 +132,7 @@ if (!c) return -ENOMEM; - n = readlinkat(fd, p, c, l); + n = readlinkat(fd, strempty(p), c, l); if (n < 0) return -errno; diff -Nru systemd-252.22/src/basic/missing_syscall.h systemd-252.23/src/basic/missing_syscall.h --- systemd-252.22/src/basic/missing_syscall.h 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/basic/missing_syscall.h 2024-02-28 16:57:11.000000000 +0000 @@ -383,23 +383,14 @@ /* ======================================================================= */ #if !HAVE_CLOSE_RANGE -static inline int missing_close_range(int first_fd, int end_fd, unsigned flags) { +static inline int missing_close_range(unsigned first_fd, unsigned end_fd, unsigned flags) { # ifdef __NR_close_range /* Kernel-side the syscall expects fds as unsigned integers (just like close() actually), while - * userspace exclusively uses signed integers for fds. We don't know just yet how glibc is going to - * wrap this syscall, but let's assume it's going to be similar to what they do for close(), - * i.e. make the same unsigned → signed type change from the raw kernel syscall compared to the - * userspace wrapper. There's only one caveat for this: unlike for close() there's the special - * UINT_MAX fd value for the 'end_fd' argument. Let's safely map that to -1 here. And let's refuse - * any other negative values. */ - if ((first_fd < 0) || (end_fd < 0 && end_fd != -1)) { - errno = -EBADF; - return -1; - } - + * userspace exclusively uses signed integers for fds. glibc chose to expose it 1:1 however, hence we + * do so here too, even if we end up passing signed fds to it most of the time. */ return syscall(__NR_close_range, - (unsigned) first_fd, - end_fd == -1 ? UINT_MAX : (unsigned) end_fd, /* Of course, the compiler should figure out that this is the identity mapping IRL */ + first_fd, + end_fd, flags); # else errno = ENOSYS; diff -Nru systemd-252.22/src/basic/missing_syscall_def.h systemd-252.23/src/basic/missing_syscall_def.h --- systemd-252.22/src/basic/missing_syscall_def.h 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/basic/missing_syscall_def.h 2024-02-28 16:57:11.000000000 +0000 @@ -14,7 +14,7 @@ # elif defined(__arm__) # elif defined(__i386__) # elif defined(__ia64__) -# elif defined(__loongarch64) +# elif defined(__loongarch_lp64) # elif defined(__m68k__) # elif defined(_MIPS_SIM) # if _MIPS_SIM == _MIPS_SIM_ABI32 @@ -55,7 +55,7 @@ # define systemd_NR_bpf 357 # elif defined(__ia64__) # define systemd_NR_bpf 1341 -# elif defined(__loongarch64) +# elif defined(__loongarch_lp64) # define systemd_NR_bpf 280 # elif defined(__m68k__) # define systemd_NR_bpf 354 @@ -123,7 +123,7 @@ # define systemd_NR_close_range 436 # elif defined(__ia64__) # define systemd_NR_close_range 1460 -# elif defined(__loongarch64) +# elif defined(__loongarch_lp64) # define systemd_NR_close_range 436 # elif defined(__m68k__) # define systemd_NR_close_range 436 @@ -191,7 +191,7 @@ # define systemd_NR_copy_file_range 377 # elif defined(__ia64__) # define systemd_NR_copy_file_range 1347 -# elif defined(__loongarch64) +# elif defined(__loongarch_lp64) # define systemd_NR_copy_file_range 285 # elif defined(__m68k__) # define systemd_NR_copy_file_range 376 @@ -314,6 +314,74 @@ # endif #endif +#ifndef __IGNORE_fchmodat2 +# if defined(__aarch64__) +# define systemd_NR_fchmodat2 452 +# elif defined(__alpha__) +# define systemd_NR_fchmodat2 562 +# elif defined(__arc__) || defined(__tilegx__) +# define systemd_NR_fchmodat2 452 +# elif defined(__arm__) +# define systemd_NR_fchmodat2 452 +# elif defined(__i386__) +# define systemd_NR_fchmodat2 452 +# elif defined(__ia64__) +# define systemd_NR_fchmodat2 1476 +# elif defined(__loongarch_lp64) +# define systemd_NR_fchmodat2 452 +# elif defined(__m68k__) +# define systemd_NR_fchmodat2 452 +# elif defined(_MIPS_SIM) +# if _MIPS_SIM == _MIPS_SIM_ABI32 +# define systemd_NR_fchmodat2 4452 +# elif _MIPS_SIM == _MIPS_SIM_NABI32 +# define systemd_NR_fchmodat2 6452 +# elif _MIPS_SIM == _MIPS_SIM_ABI64 +# define systemd_NR_fchmodat2 5452 +# else +# error "Unknown MIPS ABI" +# endif +# elif defined(__hppa__) +# define systemd_NR_fchmodat2 452 +# elif defined(__powerpc__) +# define systemd_NR_fchmodat2 452 +# elif defined(__riscv) +# if __riscv_xlen == 32 +# define systemd_NR_fchmodat2 452 +# elif __riscv_xlen == 64 +# define systemd_NR_fchmodat2 452 +# else +# error "Unknown RISC-V ABI" +# endif +# elif defined(__s390__) +# define systemd_NR_fchmodat2 452 +# elif defined(__sparc__) +# define systemd_NR_fchmodat2 452 +# elif defined(__x86_64__) +# if defined(__ILP32__) +# define systemd_NR_fchmodat2 (452 | /* __X32_SYSCALL_BIT */ 0x40000000) +# else +# define systemd_NR_fchmodat2 452 +# endif +# elif !defined(missing_arch_template) +# warning "fchmodat2() syscall number is unknown for your architecture" +# endif + +/* may be an (invalid) negative number due to libseccomp, see PR 13319 */ +# if defined __NR_fchmodat2 && __NR_fchmodat2 >= 0 +# if defined systemd_NR_fchmodat2 +assert_cc(__NR_fchmodat2 == systemd_NR_fchmodat2); +# endif +# else +# if defined __NR_fchmodat2 +# undef __NR_fchmodat2 +# endif +# if defined systemd_NR_fchmodat2 && systemd_NR_fchmodat2 >= 0 +# define __NR_fchmodat2 systemd_NR_fchmodat2 +# endif +# endif +#endif + #ifndef __IGNORE_getrandom # if defined(__aarch64__) # define systemd_NR_getrandom 278 @@ -327,7 +395,7 @@ # define systemd_NR_getrandom 355 # elif defined(__ia64__) # define systemd_NR_getrandom 1339 -# elif defined(__loongarch64) +# elif defined(__loongarch_lp64) # define systemd_NR_getrandom 278 # elif defined(__m68k__) # define systemd_NR_getrandom 352 @@ -395,7 +463,7 @@ # define systemd_NR_memfd_create 356 # elif defined(__ia64__) # define systemd_NR_memfd_create 1340 -# elif defined(__loongarch64) +# elif defined(__loongarch_lp64) # define systemd_NR_memfd_create 279 # elif defined(__m68k__) # define systemd_NR_memfd_create 353 @@ -463,7 +531,7 @@ # define systemd_NR_mount_setattr 442 # elif defined(__ia64__) # define systemd_NR_mount_setattr 1466 -# elif defined(__loongarch64) +# elif defined(__loongarch_lp64) # define systemd_NR_mount_setattr 442 # elif defined(__m68k__) # define systemd_NR_mount_setattr 442 @@ -531,7 +599,7 @@ # define systemd_NR_move_mount 429 # elif defined(__ia64__) # define systemd_NR_move_mount 1453 -# elif defined(__loongarch64) +# elif defined(__loongarch_lp64) # define systemd_NR_move_mount 429 # elif defined(__m68k__) # define systemd_NR_move_mount 429 @@ -599,7 +667,7 @@ # define systemd_NR_name_to_handle_at 341 # elif defined(__ia64__) # define systemd_NR_name_to_handle_at 1326 -# elif defined(__loongarch64) +# elif defined(__loongarch_lp64) # define systemd_NR_name_to_handle_at 264 # elif defined(__m68k__) # define systemd_NR_name_to_handle_at 340 @@ -667,7 +735,7 @@ # define systemd_NR_open_tree 428 # elif defined(__ia64__) # define systemd_NR_open_tree 1452 -# elif defined(__loongarch64) +# elif defined(__loongarch_lp64) # define systemd_NR_open_tree 428 # elif defined(__m68k__) # define systemd_NR_open_tree 428 @@ -735,7 +803,7 @@ # define systemd_NR_openat2 437 # elif defined(__ia64__) # define systemd_NR_openat2 1461 -# elif defined(__loongarch64) +# elif defined(__loongarch_lp64) # define systemd_NR_openat2 437 # elif defined(__m68k__) # define systemd_NR_openat2 437 @@ -803,7 +871,7 @@ # define systemd_NR_pidfd_open 434 # elif defined(__ia64__) # define systemd_NR_pidfd_open 1458 -# elif defined(__loongarch64) +# elif defined(__loongarch_lp64) # define systemd_NR_pidfd_open 434 # elif defined(__m68k__) # define systemd_NR_pidfd_open 434 @@ -871,7 +939,7 @@ # define systemd_NR_pidfd_send_signal 424 # elif defined(__ia64__) # define systemd_NR_pidfd_send_signal 1448 -# elif defined(__loongarch64) +# elif defined(__loongarch_lp64) # define systemd_NR_pidfd_send_signal 424 # elif defined(__m68k__) # define systemd_NR_pidfd_send_signal 424 @@ -939,7 +1007,7 @@ # define systemd_NR_pkey_mprotect 380 # elif defined(__ia64__) # define systemd_NR_pkey_mprotect 1354 -# elif defined(__loongarch64) +# elif defined(__loongarch_lp64) # define systemd_NR_pkey_mprotect 288 # elif defined(__m68k__) # define systemd_NR_pkey_mprotect 381 @@ -1007,7 +1075,7 @@ # define systemd_NR_renameat2 353 # elif defined(__ia64__) # define systemd_NR_renameat2 1338 -# elif defined(__loongarch64) +# elif defined(__loongarch_lp64) # define systemd_NR_renameat2 276 # elif defined(__m68k__) # define systemd_NR_renameat2 351 @@ -1075,7 +1143,7 @@ # define systemd_NR_setns 346 # elif defined(__ia64__) # define systemd_NR_setns 1330 -# elif defined(__loongarch64) +# elif defined(__loongarch_lp64) # define systemd_NR_setns 268 # elif defined(__m68k__) # define systemd_NR_setns 344 @@ -1143,7 +1211,7 @@ # define systemd_NR_statx 383 # elif defined(__ia64__) # define systemd_NR_statx 1350 -# elif defined(__loongarch64) +# elif defined(__loongarch_lp64) # define systemd_NR_statx 291 # elif defined(__m68k__) # define systemd_NR_statx 379 diff -Nru systemd-252.22/src/basic/missing_syscalls.py systemd-252.23/src/basic/missing_syscalls.py --- systemd-252.22/src/basic/missing_syscalls.py 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/basic/missing_syscalls.py 2024-02-28 16:57:11.000000000 +0000 @@ -10,6 +10,7 @@ 'close_range', 'copy_file_range', 'epoll_pwait2', + 'fchmodat2', 'getrandom', 'memfd_create', 'mount_setattr', @@ -60,7 +61,7 @@ # define systemd_NR_{syscall} {nr_i386} # elif defined(__ia64__) # define systemd_NR_{syscall} {nr_ia64} -# elif defined(__loongarch64) +# elif defined(__loongarch_lp64) # define systemd_NR_{syscall} {nr_loongarch64} # elif defined(__m68k__) # define systemd_NR_{syscall} {nr_m68k} diff -Nru systemd-252.22/src/basic/string-util.c systemd-252.23/src/basic/string-util.c --- systemd-252.22/src/basic/string-util.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/basic/string-util.c 2024-02-28 16:57:11.000000000 +0000 @@ -1202,3 +1202,15 @@ return n; } + +char *startswith_strv(const char *string, char **strv) { + char *found = NULL; + + STRV_FOREACH(i, strv) { + found = startswith(string, *i); + if (found) + break; + } + + return found; +} diff -Nru systemd-252.22/src/basic/string-util.h systemd-252.23/src/basic/string-util.h --- systemd-252.22/src/basic/string-util.h 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/basic/string-util.h 2024-02-28 16:57:11.000000000 +0000 @@ -243,3 +243,8 @@ char *string_replace_char(char *str, char old_char, char new_char); size_t strspn_from_end(const char *str, const char *accept); + +char *startswith_strv(const char *string, char **strv); + +#define STARTSWITH_SET(p, ...) \ + startswith_strv(p, STRV_MAKE(__VA_ARGS__)) diff -Nru systemd-252.22/src/basic/strv.h systemd-252.23/src/basic/strv.h --- systemd-252.22/src/basic/strv.h 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/basic/strv.h 2024-02-28 16:57:11.000000000 +0000 @@ -206,18 +206,6 @@ _x && strv_contains_case(STRV_MAKE(__VA_ARGS__), _x); \ }) -#define STARTSWITH_SET(p, ...) \ - ({ \ - const char *_p = (p); \ - char *_found = NULL; \ - STRV_FOREACH(_i, STRV_MAKE(__VA_ARGS__)) { \ - _found = startswith(_p, *_i); \ - if (_found) \ - break; \ - } \ - _found; \ - }) - #define ENDSWITH_SET(p, ...) \ ({ \ const char *_p = (p); \ diff -Nru systemd-252.22/src/basic/user-util.c systemd-252.23/src/basic/user-util.c --- systemd-252.22/src/basic/user-util.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/basic/user-util.c 2024-02-28 16:57:11.000000000 +0000 @@ -313,7 +313,7 @@ if (shell) { if (FLAGS_SET(flags, USER_CREDS_CLEAN) && (isempty(p->pw_shell) || - !path_is_valid(p->pw_dir) || + !path_is_valid(p->pw_shell) || !path_is_absolute(p->pw_shell) || is_nologin_shell(p->pw_shell))) *shell = NULL; diff -Nru systemd-252.22/src/basic/virt.c systemd-252.23/src/basic/virt.c --- systemd-252.22/src/basic/virt.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/basic/virt.c 2024-02-28 16:57:11.000000000 +0000 @@ -97,7 +97,7 @@ } static Virtualization detect_vm_device_tree(void) { -#if defined(__arm__) || defined(__aarch64__) || defined(__powerpc__) || defined(__powerpc64__) +#if defined(__arm__) || defined(__aarch64__) || defined(__powerpc__) || defined(__powerpc64__) || defined(__riscv) _cleanup_free_ char *hvtype = NULL; int r; @@ -154,7 +154,7 @@ #endif } -#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) || defined(__loongarch64) +#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) || defined(__loongarch_lp64) || defined(__riscv) static Virtualization detect_vm_dmi_vendor(void) { static const char* const dmi_vendors[] = { "/sys/class/dmi/id/product_name", /* Test this before sys_vendor to detect KVM over QEMU */ @@ -245,10 +245,10 @@ log_debug("DMI BIOS Extension table does not indicate virtualization."); return SMBIOS_VM_BIT_UNSET; } -#endif /* defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) || defined(__loongarch64) */ +#endif /* defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) || defined(__loongarch_lp64) */ static Virtualization detect_vm_dmi(void) { -#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) || defined(__loongarch64) +#if defined(__i386__) || defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) || defined(__loongarch_lp64) int r; r = detect_vm_dmi_vendor(); @@ -454,7 +454,7 @@ /* We have to use the correct order here: * - * → First, try to detect Oracle Virtualbox, Amazon EC2 Nitro, and Parallels, even if they use KVM, + * → First, try to detect Oracle Virtualbox, Amazon EC2 Nitro, Parallels, and Google Compute Engine, even if they use KVM, * as well as Xen even if it cloaks as Microsoft Hyper-V. Attempt to detect uml at this stage also * since it runs as a user-process nested inside other VMs. Also check for Xen now, because Xen PV * mode does not override CPUID when nested inside another hypervisor. @@ -469,7 +469,8 @@ VIRTUALIZATION_ORACLE, VIRTUALIZATION_XEN, VIRTUALIZATION_AMAZON, - VIRTUALIZATION_PARALLELS)) { + VIRTUALIZATION_PARALLELS, + VIRTUALIZATION_GOOGLE)) { v = dmi; goto finish; } diff -Nru systemd-252.22/src/core/dbus-cgroup.c systemd-252.23/src/core/dbus-cgroup.c --- systemd-252.22/src/core/dbus-cgroup.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/core/dbus-cgroup.c 2024-02-28 16:57:11.000000000 +0000 @@ -519,7 +519,7 @@ if (!UNIT_WRITE_FLAGS_NOOP(flags)) { c->delegate = b; - c->delegate_controllers = b ? _CGROUP_MASK_ALL : 0; + c->delegate_controllers = b ? CGROUP_MASK_DELEGATE : 0; unit_write_settingf(u, flags, name, "Delegate=%s", yes_no(b)); } diff -Nru systemd-252.22/src/core/dbus-execute.c systemd-252.23/src/core/dbus-execute.c --- systemd-252.22/src/core/dbus-execute.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/core/dbus-execute.c 2024-02-28 16:57:11.000000000 +0000 @@ -728,7 +728,7 @@ c->bind_mounts[i].source, c->bind_mounts[i].destination, c->bind_mounts[i].ignore_enoent, - c->bind_mounts[i].recursive ? (uint64_t) MS_REC : (uint64_t) 0); + c->bind_mounts[i].recursive ? (uint64_t) MS_REC : UINT64_C(0)); if (r < 0) return r; } @@ -1100,7 +1100,7 @@ for (size_t i = 0; i < d->n_items; i++) STRV_FOREACH(dst, d->items[i].symlinks) { - r = sd_bus_message_append(reply, "(sst)", d->items[i].path, *dst, 0 /* flags, unused for now */); + r = sd_bus_message_append(reply, "(sst)", d->items[i].path, *dst, UINT64_C(0) /* flags, unused for now */); if (r < 0) return r; } diff -Nru systemd-252.22/src/core/execute.c systemd-252.23/src/core/execute.c --- systemd-252.22/src/core/execute.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/core/execute.c 2024-02-28 16:57:11.000000000 +0000 @@ -4512,6 +4512,16 @@ } if (context->utmp_id) { + _cleanup_free_ char *username_alloc = NULL; + + if (!username && context->utmp_mode == EXEC_UTMP_USER) { + username_alloc = uid_to_name(uid_is_valid(uid) ? uid : saved_uid); + if (!username_alloc) { + *exit_status = EXIT_USER; + return log_oom(); + } + } + const char *line = context->tty_path ? (path_startswith(context->tty_path, "/dev/") ?: context->tty_path) : NULL; @@ -4520,7 +4530,7 @@ context->utmp_mode == EXEC_UTMP_INIT ? INIT_PROCESS : context->utmp_mode == EXEC_UTMP_LOGIN ? LOGIN_PROCESS : USER_PROCESS, - username); + username ?: username_alloc); } if (uid_is_valid(uid)) { diff -Nru systemd-252.22/src/core/kmod-setup.c systemd-252.23/src/core/kmod-setup.c --- systemd-252.22/src/core/kmod-setup.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/core/kmod-setup.c 2024-02-28 16:57:11.000000000 +0000 @@ -30,7 +30,7 @@ REENABLE_WARNING; } -static int has_virtio_rng_recurse_dir_cb( +static int match_modalias_recurse_dir_cb( RecurseDirEvent event, const char *path, int dir_fd, @@ -40,6 +40,7 @@ void *userdata) { _cleanup_free_ char *alias = NULL; + char **modaliases = ASSERT_PTR(userdata); int r; if (event != RECURSE_DIR_ENTRY) @@ -57,13 +58,13 @@ return RECURSE_DIR_LEAVE_DIRECTORY; } - if (STARTSWITH_SET(alias, "pci:v00001AF4d00001005", "pci:v00001AF4d00001044")) + if (startswith_strv(alias, modaliases)) return 1; return RECURSE_DIR_LEAVE_DIRECTORY; } -static bool has_virtio_rng(void) { +static bool has_virtio_feature(const char *name, char **modaliases) { int r; /* Directory traversal might be slow, hence let's do a cheap check first if it's even worth it */ @@ -74,16 +75,28 @@ AT_FDCWD, "/sys/devices/pci0000:00", /* statx_mask= */ 0, - /* n_depth_max= */ 2, + /* n_depth_max= */ 3, RECURSE_DIR_ENSURE_TYPE, - has_virtio_rng_recurse_dir_cb, - NULL); + match_modalias_recurse_dir_cb, + modaliases); if (r < 0) - log_debug_errno(r, "Failed to determine whether host has virtio-rng device, ignoring: %m"); + log_debug_errno(r, "Failed to determine whether host has %s device, ignoring: %m", name); return r > 0; } +static bool has_virtio_rng(void) { + return has_virtio_feature("virtio-rng", STRV_MAKE("pci:v00001AF4d00001005", "pci:v00001AF4d00001044")); +} + +static bool has_virtiofs(void) { + return has_virtio_feature("virtiofs", STRV_MAKE("virtio:d0000001Av")); +} + +static bool has_virtio_pci(void) { + return has_virtio_feature("virtio-pci", STRV_MAKE("pci:v00001AF4d")); +} + static bool in_qemu(void) { return IN_SET(detect_vm(), VIRTUALIZATION_KVM, VIRTUALIZATION_QEMU); } @@ -117,6 +130,15 @@ /* virtio_rng would be loaded by udev later, but real entropy might be needed very early */ { "virtio_rng", NULL, false, false, has_virtio_rng }, + /* We can't wait for specific virtiofs tags to show up as device nodes so we have to load the + * virtiofs and virtio_pci modules early to make sure the virtiofs tags are found when + * sysroot.mount is started. + * + * TODO: Remove these again once https://gitlab.com/virtio-fs/virtiofsd/-/issues/128 is + * resolved and the kernel fix is widely available. */ + { "virtiofs", "/sys/module/virtiofs", false, false, has_virtiofs }, + { "virtio_pci", "/sys/module/virtio_pci", false, false, has_virtio_pci }, + /* qemu_fw_cfg would be loaded by udev later, but we want to import credentials from it super early */ { "qemu_fw_cfg", "/sys/firmware/qemu_fw_cfg", false, false, in_qemu }, diff -Nru systemd-252.22/src/core/load-fragment.c systemd-252.23/src/core/load-fragment.c --- systemd-252.22/src/core/load-fragment.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/core/load-fragment.c 2024-02-28 16:57:11.000000000 +0000 @@ -3990,7 +3990,7 @@ } else if (r > 0) { c->delegate = true; - c->delegate_controllers = _CGROUP_MASK_ALL; + c->delegate_controllers = CGROUP_MASK_DELEGATE; } else { c->delegate = false; c->delegate_controllers = 0; diff -Nru systemd-252.22/src/core/service.c systemd-252.23/src/core/service.c --- systemd-252.22/src/core/service.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/core/service.c 2024-02-28 16:57:11.000000000 +0000 @@ -594,8 +594,7 @@ if (s->type != SERVICE_ONESHOT && s->exec_command[SERVICE_EXEC_START]->command_next) return log_unit_error_errno(UNIT(s), SYNTHETIC_ERRNO(ENOEXEC), "Service has more than one ExecStart= setting, which is only allowed for Type=oneshot services. Refusing."); - if (s->type == SERVICE_ONESHOT && - !IN_SET(s->restart, SERVICE_RESTART_NO, SERVICE_RESTART_ON_FAILURE, SERVICE_RESTART_ON_ABNORMAL, SERVICE_RESTART_ON_WATCHDOG, SERVICE_RESTART_ON_ABORT)) + if (s->type == SERVICE_ONESHOT && IN_SET(s->restart, SERVICE_RESTART_ALWAYS, SERVICE_RESTART_ON_SUCCESS)) return log_unit_error_errno(UNIT(s), SYNTHETIC_ERRNO(ENOEXEC), "Service has Restart= set to either always or on-success, which isn't allowed for Type=oneshot services. Refusing."); if (s->type == SERVICE_ONESHOT && !exit_status_set_is_empty(&s->restart_force_status)) diff -Nru systemd-252.22/src/libsystemd/sd-bus/bus-socket.c systemd-252.23/src/libsystemd/sd-bus/bus-socket.c --- systemd-252.22/src/libsystemd/sd-bus/bus-socket.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/libsystemd/sd-bus/bus-socket.c 2024-02-28 16:57:11.000000000 +0000 @@ -725,12 +725,12 @@ assert(b->sockaddr.sa.sa_family == AF_UNIX); assert(b->sockaddr.un.sun_path[0] != 0); - /* Sets up an inotify fd in case watch_bind is enabled: wait until the configured AF_UNIX file system socket - * appears before connecting to it. The implemented is pretty simplistic: we just subscribe to relevant changes - * to all prefix components of the path, and every time we get an event for that we try to reconnect again, - * without actually caring what precisely the event we got told us. If we still can't connect we re-subscribe - * to all relevant changes of anything in the path, so that our watches include any possibly newly created path - * components. */ + /* Sets up an inotify fd in case watch_bind is enabled: wait until the configured AF_UNIX file system + * socket appears before connecting to it. The implemented is pretty simplistic: we just subscribe to + * relevant changes to all components of the path, and every time we get an event for that we try to + * reconnect again, without actually caring what precisely the event we got told us. If we still + * can't connect we re-subscribe to all relevant changes of anything in the path, so that our watches + * include any possibly newly created path components. */ if (b->inotify_fd < 0) { b->inotify_fd = inotify_init1(IN_NONBLOCK|IN_CLOEXEC); @@ -749,17 +749,17 @@ if (r < 0) goto fail; - /* Watch all parent directories, and don't mind any prefix that doesn't exist yet. For the innermost directory - * that exists we want to know when files are created or moved into it. For all parents of it we just care if - * they are removed or renamed. */ + /* Watch all components of the path, and don't mind any prefix that doesn't exist yet. For the + * innermost directory that exists we want to know when files are created or moved into it. For all + * parents of it we just care if they are removed or renamed. */ if (!GREEDY_REALLOC(new_watches, n + 1)) { r = -ENOMEM; goto fail; } - /* Start with the top-level directory, which is a bit simpler than the rest, since it can't be a symlink, and - * always exists */ + /* Start with the top-level directory, which is a bit simpler than the rest, since it can't be a + * symlink, and always exists */ wd = inotify_add_watch(b->inotify_fd, "/", IN_CREATE|IN_MOVED_TO); if (wd < 0) { r = log_debug_errno(errno, "Failed to add inotify watch on /: %m"); diff -Nru systemd-252.22/src/libsystemd/sd-bus/sd-bus.c systemd-252.23/src/libsystemd/sd-bus/sd-bus.c --- systemd-252.22/src/libsystemd/sd-bus/sd-bus.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/libsystemd/sd-bus/sd-bus.c 2024-02-28 16:57:11.000000000 +0000 @@ -3040,7 +3040,7 @@ return r; } -static int bus_exit_now(sd_bus *bus) { +static int bus_exit_now(sd_bus *bus, sd_event *event) { assert(bus); /* Exit due to close, if this is requested. If this is bus object is attached to an event source, invokes @@ -3057,8 +3057,11 @@ log_debug("Bus connection disconnected, exiting."); - if (bus->event) - return sd_event_exit(bus->event, EXIT_FAILURE); + if (!event) + event = bus->event; + + if (event) + return sd_event_exit(event, EXIT_FAILURE); else exit(EXIT_FAILURE); @@ -3120,6 +3123,7 @@ static int process_closing(sd_bus *bus, sd_bus_message **ret) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL; + _cleanup_(sd_event_unrefp) sd_event *event = NULL; struct reply_callback *c; int r; @@ -3154,6 +3158,10 @@ if (r < 0) return r; + /* sd_bus_close() will deref the event and set bus->event to NULL. But in bus_exit_now() we use + * bus->event to decide whether to return from the event loop or exit(), but given it's always NULL + * at that point, it always exit(). Ref it here and pass it through further down to avoid that. */ + event = sd_event_ref(bus->event); sd_bus_close(bus); bus->current_message = m; @@ -3169,7 +3177,7 @@ /* Nothing else to do, exit now, if the condition holds */ bus->exit_triggered = true; - (void) bus_exit_now(bus); + (void) bus_exit_now(bus, event); if (ret) *ret = TAKE_PTR(m); @@ -4281,7 +4289,7 @@ bus->exit_on_disconnect = b; /* If the exit condition was triggered already, exit immediately. */ - return bus_exit_now(bus); + return bus_exit_now(bus, /* event= */ NULL); } _public_ int sd_bus_get_exit_on_disconnect(sd_bus *bus) { diff -Nru systemd-252.22/src/libsystemd/sd-bus/test-bus-watch-bind.c systemd-252.23/src/libsystemd/sd-bus/test-bus-watch-bind.c --- systemd-252.22/src/libsystemd/sd-bus/test-bus-watch-bind.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/libsystemd/sd-bus/test-bus-watch-bind.c 2024-02-28 16:57:11.000000000 +0000 @@ -7,6 +7,7 @@ #include "sd-id128.h" #include "alloc-util.h" +#include "bus-internal.h" #include "fd-util.h" #include "fs-util.h" #include "mkdir.h" @@ -27,8 +28,11 @@ static int method_exit(sd_bus_message *m, void *userdata, sd_bus_error *ret_error) { log_info("Got Exit() call"); - assert_se(sd_event_exit(sd_bus_get_event(sd_bus_message_get_bus(m)), 1) >= 0); - return sd_bus_reply_method_return(m, NULL); + + assert_se(sd_bus_reply_method_return(m, NULL) >= 0); + /* Simulate D-Bus going away to test the bus_exit_now() path with exit_on_disconnect set */ + bus_enter_closing(sd_bus_message_get_bus(m)); + return 0; } static const sd_bus_vtable vtable[] = { @@ -100,6 +104,7 @@ log_debug("Accepted server connection"); assert_se(sd_bus_new(&bus) >= 0); + assert_se(sd_bus_set_exit_on_disconnect(bus, true) >= 0); assert_se(sd_bus_set_description(bus, "server") >= 0); assert_se(sd_bus_set_fd(bus, bus_fd, bus_fd) >= 0); assert_se(sd_bus_set_server(bus, true, id) >= 0); diff -Nru systemd-252.22/src/libsystemd/sd-id128/id128-util.c systemd-252.23/src/libsystemd/sd-id128/id128-util.c --- systemd-252.22/src/libsystemd/sd-id128/id128-util.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/libsystemd/sd-id128/id128-util.c 2024-02-28 16:57:11.000000000 +0000 @@ -192,6 +192,8 @@ r = id128_read("/sys/class/dmi/id/product_uuid", ID128_FORMAT_UUID, &uuid); if (r == -ENOENT) r = id128_read("/proc/device-tree/vm,uuid", ID128_FORMAT_UUID, &uuid); + if (r == -ENOENT) + r = id128_read("/sys/hypervisor/uuid", ID128_FORMAT_UUID, &uuid); if (r < 0) return r; diff -Nru systemd-252.22/src/login/user-runtime-dir.c systemd-252.23/src/login/user-runtime-dir.c --- systemd-252.22/src/login/user-runtime-dir.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/login/user-runtime-dir.c 2024-02-28 16:57:11.000000000 +0000 @@ -66,7 +66,7 @@ if (r < 0) return log_error_errno(r, "Failed to create /run/user: %m"); - if (path_is_mount_point(runtime_path, NULL, 0) >= 0) + if (path_is_mount_point(runtime_path, NULL, 0) > 0) log_debug("%s is already a mount point", runtime_path); else { char options[sizeof("mode=0700,uid=,gid=,size=,nr_inodes=,smackfsroot=*") diff -Nru systemd-252.22/src/machine/machinectl.c systemd-252.23/src/machine/machinectl.c --- systemd-252.22/src/machine/machinectl.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/machine/machinectl.c 2024-02-28 16:57:11.000000000 +0000 @@ -1127,7 +1127,7 @@ return bus_log_create_error(r); if (arg_force) { - r = sd_bus_message_append(m, "t", MACHINE_COPY_REPLACE); + r = sd_bus_message_append(m, "t", (uint64_t) MACHINE_COPY_REPLACE); if (r < 0) return bus_log_create_error(r); } diff -Nru systemd-252.22/src/network/wait-online/manager.c systemd-252.23/src/network/wait-online/manager.c --- systemd-252.22/src/network/wait-online/manager.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/network/wait-online/manager.c 2024-02-28 16:57:11.000000000 +0000 @@ -158,7 +158,9 @@ r = manager_link_is_online(m, l, (LinkOperationalStateRange) { _LINK_OPERSTATE_INVALID, _LINK_OPERSTATE_INVALID }); - if (r < 0 && !m->any) /* Unlike the above loop, unmanaged interfaces are ignored here. */ + /* Unlike the above loop, unmanaged interfaces are ignored here. Also, Configured but offline + * interfaces are ignored. See issue #29506. */ + if (r < 0 && r != -EADDRNOTAVAIL && !m->any) return false; if (r > 0) { if (m->any) diff -Nru systemd-252.22/src/nspawn/nspawn.c systemd-252.23/src/nspawn/nspawn.c --- systemd-252.22/src/nspawn/nspawn.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/nspawn/nspawn.c 2024-02-28 16:57:11.000000000 +0000 @@ -1805,8 +1805,10 @@ if (arg_ephemeral && arg_template) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--ephemeral and --template= may not be combined."); - if (arg_ephemeral && !IN_SET(arg_link_journal, LINK_NO, LINK_AUTO)) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--ephemeral and --link-journal= may not be combined."); + /* Permit --ephemeral with --link-journal=try-* to satisfy principle of the least astonishment + * (by common sense, "try" means "do not fail if not possible") */ + if (arg_ephemeral && !IN_SET(arg_link_journal, LINK_NO, LINK_AUTO) && !arg_link_journal_try) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "--ephemeral and --link-journal={host,guest} may not be combined."); if (arg_userns_mode != USER_NAMESPACE_NO && !userns_supported()) return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "--private-users= is not supported, kernel compiled without user namespace support."); diff -Nru systemd-252.22/src/portable/portablectl.c systemd-252.23/src/portable/portablectl.c --- systemd-252.22/src/portable/portablectl.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/portable/portablectl.c 2024-02-28 16:57:11.000000000 +0000 @@ -1157,7 +1157,7 @@ return r; if (!strv_isempty(arg_extension_images)) { - r = sd_bus_message_append(m, "t", 0); + r = sd_bus_message_append(m, "t", UINT64_C(0)); if (r < 0) return bus_log_create_error(r); } diff -Nru systemd-252.22/src/resolve/resolved-dns-dnssec.c systemd-252.23/src/resolve/resolved-dns-dnssec.c --- systemd-252.22/src/resolve/resolved-dns-dnssec.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/resolve/resolved-dns-dnssec.c 2024-02-28 16:57:11.000000000 +0000 @@ -27,8 +27,9 @@ /* Permit a maximum clock skew of 1h 10min. This should be enough to deal with DST confusion */ #define SKEW_MAX (1*USEC_PER_HOUR + 10*USEC_PER_MINUTE) -/* Maximum number of NSEC3 iterations we'll do. RFC5155 says 2500 shall be the maximum useful value */ -#define NSEC3_ITERATIONS_MAX 2500 +/* Maximum number of NSEC3 iterations we'll do. RFC5155 says 2500 shall be the maximum useful value, but + * RFC9276 § 3.2 says that we should reduce the acceptable iteration count */ +#define NSEC3_ITERATIONS_MAX 100 /* * The DNSSEC Chain of trust: @@ -1176,6 +1177,7 @@ DnsResourceRecord **ret_rrsig) { bool found_rrsig = false, found_invalid = false, found_expired_rrsig = false, found_unsupported_algorithm = false; + unsigned nvalidations = 0; DnsResourceRecord *rrsig; int r; @@ -1221,6 +1223,14 @@ if (realtime == USEC_INFINITY) realtime = now(CLOCK_REALTIME); + /* Have we seen an unreasonable number of invalid signaures? */ + if (nvalidations > DNSSEC_INVALID_MAX) { + if (ret_rrsig) + *ret_rrsig = NULL; + *result = DNSSEC_TOO_MANY_VALIDATIONS; + return (int) nvalidations; + } + /* Yay, we found a matching RRSIG with a matching * DNSKEY, awesome. Now let's verify all entries of * the RRSet against the RRSIG and DNSKEY @@ -1230,6 +1240,8 @@ if (r < 0) return r; + nvalidations++; + switch (one_result) { case DNSSEC_VALIDATED: @@ -1240,7 +1252,7 @@ *ret_rrsig = rrsig; *result = one_result; - return 0; + return (int) nvalidations; case DNSSEC_INVALID: /* If the signature is invalid, let's try another @@ -1287,7 +1299,7 @@ if (ret_rrsig) *ret_rrsig = NULL; - return 0; + return (int) nvalidations; } int dnssec_has_rrsig(DnsAnswer *a, const DnsResourceKey *key) { @@ -2571,6 +2583,7 @@ [DNSSEC_FAILED_AUXILIARY] = "failed-auxiliary", [DNSSEC_NSEC_MISMATCH] = "nsec-mismatch", [DNSSEC_INCOMPATIBLE_SERVER] = "incompatible-server", + [DNSSEC_TOO_MANY_VALIDATIONS] = "too-many-validations", }; DEFINE_STRING_TABLE_LOOKUP(dnssec_result, DnssecResult); diff -Nru systemd-252.22/src/resolve/resolved-dns-dnssec.h systemd-252.23/src/resolve/resolved-dns-dnssec.h --- systemd-252.22/src/resolve/resolved-dns-dnssec.h 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/resolve/resolved-dns-dnssec.h 2024-02-28 16:57:11.000000000 +0000 @@ -9,12 +9,13 @@ #include "resolved-dns-rr.h" enum DnssecResult { - /* These five are returned by dnssec_verify_rrset() */ + /* These six are returned by dnssec_verify_rrset() */ DNSSEC_VALIDATED, DNSSEC_VALIDATED_WILDCARD, /* Validated via a wildcard RRSIG, further NSEC/NSEC3 checks necessary */ DNSSEC_INVALID, DNSSEC_SIGNATURE_EXPIRED, DNSSEC_UNSUPPORTED_ALGORITHM, + DNSSEC_TOO_MANY_VALIDATIONS, /* These two are added by dnssec_verify_rrset_search() */ DNSSEC_NO_SIGNATURE, @@ -45,6 +46,12 @@ /* The longest digest we'll ever generate, of all digest algorithms we support */ #define DNSSEC_HASH_SIZE_MAX (MAX(20, 32)) +/* The most invalid signatures we will tolerate for a single rrset */ +#define DNSSEC_INVALID_MAX 5 + +/* The total number of signature validations we will tolerate for a single transaction */ +#define DNSSEC_VALIDATION_MAX 64 + int dnssec_rrsig_match_dnskey(DnsResourceRecord *rrsig, DnsResourceRecord *dnskey, bool revoked_ok); int dnssec_key_match_rrsig(const DnsResourceKey *key, DnsResourceRecord *rrsig); diff -Nru systemd-252.22/src/resolve/resolved-dns-transaction.c systemd-252.23/src/resolve/resolved-dns-transaction.c --- systemd-252.22/src/resolve/resolved-dns-transaction.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/resolve/resolved-dns-transaction.c 2024-02-28 16:57:11.000000000 +0000 @@ -3172,11 +3172,14 @@ DnsTransaction *t, Phase phase, bool *have_nsec, + unsigned *nvalidations, DnsAnswer **validated) { DnsResourceRecord *rr; int r; + assert(nvalidations); + /* Returns negative on error, 0 if validation failed, 1 to restart validation, 2 when finished. */ DNS_ANSWER_FOREACH(rr, t->answer) { @@ -3218,6 +3221,7 @@ &rrsig); if (r < 0) return r; + *nvalidations += r; log_debug("Looking at %s: %s", strna(dns_resource_record_to_string(rr)), dnssec_result_to_string(result)); @@ -3415,7 +3419,8 @@ DNSSEC_SIGNATURE_EXPIRED, DNSSEC_NO_SIGNATURE)) manager_dnssec_verdict(t->scope->manager, DNSSEC_BOGUS, rr->key); - else /* DNSSEC_MISSING_KEY or DNSSEC_UNSUPPORTED_ALGORITHM */ + else /* DNSSEC_MISSING_KEY, DNSSEC_UNSUPPORTED_ALGORITHM, + or DNSSEC_TOO_MANY_VALIDATIONS */ manager_dnssec_verdict(t->scope->manager, DNSSEC_INDETERMINATE, rr->key); /* This is a primary response to our question, and it failed validation. @@ -3508,13 +3513,21 @@ return r; phase = DNSSEC_PHASE_DNSKEY; - for (;;) { + for (unsigned nvalidations = 0;;) { bool have_nsec = false; - r = dnssec_validate_records(t, phase, &have_nsec, &validated); + r = dnssec_validate_records(t, phase, &have_nsec, &nvalidations, &validated); if (r <= 0) return r; + if (nvalidations > DNSSEC_VALIDATION_MAX) { + /* This reply requires an onerous number of signature validations to verify. Let's + * not waste our time trying, as this shouldn't happen for well-behaved domains + * anyway. */ + t->answer_dnssec_result = DNSSEC_TOO_MANY_VALIDATIONS; + return 0; + } + /* Try again as long as we managed to achieve something */ if (r == 1) continue; diff -Nru systemd-252.22/src/shared/base-filesystem.c systemd-252.23/src/shared/base-filesystem.c --- systemd-252.22/src/shared/base-filesystem.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/shared/base-filesystem.c 2024-02-28 16:57:11.000000000 +0000 @@ -63,7 +63,7 @@ "usr/lib64\0", "ld-linux-x86-64.so.2" }, # define KNOW_LIB64_DIRS 1 #elif defined(__ia64__) -#elif defined(__loongarch64) +#elif defined(__loongarch_lp64) # define KNOW_LIB64_DIRS 1 # if defined(__loongarch_double_float) { "lib64", 0, "usr/lib/"LIB_ARCH_TUPLE"\0" diff -Nru systemd-252.22/src/shared/bus-unit-util.c systemd-252.23/src/shared/bus-unit-util.c --- systemd-252.22/src/shared/bus-unit-util.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/shared/bus-unit-util.c 2024-02-28 16:57:11.000000000 +0000 @@ -1282,12 +1282,12 @@ if (r < 0) return log_error_errno(r, "Failed to parse resource limit: %s", eq); - r = sd_bus_message_append(m, "(sv)", field, "t", l.rlim_max); + r = sd_bus_message_append(m, "(sv)", field, "t", (uint64_t) l.rlim_max); if (r < 0) return bus_log_create_error(r); sn = strjoina(field, "Soft"); - r = sd_bus_message_append(m, "(sv)", sn, "t", l.rlim_cur); + r = sd_bus_message_append(m, "(sv)", sn, "t", (uint64_t) l.rlim_cur); if (r < 0) return bus_log_create_error(r); @@ -2030,7 +2030,7 @@ return bus_log_create_error(r); STRV_FOREACH_PAIR(source, destination, symlinks) { - r = sd_bus_message_append(m, "(sst)", *source, *destination, 0); + r = sd_bus_message_append(m, "(sst)", *source, *destination, UINT64_C(0)); if (r < 0) return bus_log_create_error(r); } diff -Nru systemd-252.22/src/shared/conf-parser.c systemd-252.23/src/shared/conf-parser.c --- systemd-252.22/src/shared/conf-parser.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/shared/conf-parser.c 2024-02-28 16:57:11.000000000 +0000 @@ -463,7 +463,7 @@ return -ENOMEM; path_copy = strdup(path); - if (!path) + if (!path_copy) return -ENOMEM; r = hashmap_put(*stats_by_path, path_copy, st_copy); diff -Nru systemd-252.22/src/shared/efi-loader.c systemd-252.23/src/shared/efi-loader.c --- systemd-252.22/src/shared/efi-loader.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/shared/efi-loader.c 2024-02-28 16:57:11.000000000 +0000 @@ -99,7 +99,8 @@ if (r < 0) return r; - /* The variable contains a series of individually NUL terminated UTF-16 strings. */ + /* The variable contains a series of individually NUL terminated UTF-16 strings. We gracefully + * consider the final NUL byte optional (i.e. the last string may or may not end in a NUL byte).*/ for (size_t i = 0, start = 0;; i++) { _cleanup_free_ char *decoded = NULL; @@ -113,6 +114,11 @@ if (!end && entries[i] != 0) continue; + /* Empty string at the end of variable? That's the trailer, we are done (i.e. we have a final + * NUL terminator). */ + if (end && start == i) + break; + /* We reached the end of a string, let's decode it into UTF-8 */ decoded = utf16_to_utf8(entries + start, (i - start) * sizeof(char16_t)); if (!decoded) @@ -125,7 +131,8 @@ } else log_debug("Ignoring invalid loader entry '%s'.", decoded); - /* We reached the end of the variable */ + /* Exit the loop if we reached the end of the variable (i.e. we do not have a final NUL + * terminator) */ if (end) break; diff -Nru systemd-252.22/src/shared/generate-syscall-list.py systemd-252.23/src/shared/generate-syscall-list.py --- systemd-252.22/src/shared/generate-syscall-list.py 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/shared/generate-syscall-list.py 2024-02-28 16:57:11.000000000 +0000 @@ -2,15 +2,6 @@ # SPDX-License-Identifier: LGPL-2.1-or-later import sys -import os - -s390 = 's390' in os.uname().machine -arm = 'arm' in os.uname().machine for line in open(sys.argv[1]): - if line.startswith('s390_') and not s390: - continue - if line.startswith('arm_') and not arm: - continue - print('"{}\\0"'.format(line.strip())) diff -Nru systemd-252.22/src/shared/keyring-util.c systemd-252.23/src/shared/keyring-util.c --- systemd-252.22/src/shared/keyring-util.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/shared/keyring-util.c 2024-02-28 16:57:11.000000000 +0000 @@ -5,34 +5,31 @@ #include "missing_syscall.h" int keyring_read(key_serial_t serial, void **ret, size_t *ret_size) { - size_t m = 100; + size_t bufsize = 100; for (;;) { - _cleanup_(erase_and_freep) uint8_t *p = NULL; + _cleanup_(erase_and_freep) uint8_t *buf = NULL; long n; - p = new(uint8_t, m+1); - if (!p) + buf = new(uint8_t, bufsize + 1); + if (!buf) return -ENOMEM; - n = keyctl(KEYCTL_READ, (unsigned long) serial, (unsigned long) p, (unsigned long) m, 0); + n = keyctl(KEYCTL_READ, (unsigned long) serial, (unsigned long) buf, (unsigned long) bufsize, 0); if (n < 0) return -errno; - if ((size_t) n <= m) { - p[n] = 0; /* NUL terminate, just in case */ + if ((size_t) n <= bufsize) { + buf[n] = 0; /* NUL terminate, just in case */ if (ret) - *ret = TAKE_PTR(p); + *ret = TAKE_PTR(buf); if (ret_size) *ret_size = n; return 0; } - if (m > (SIZE_MAX-1) / 2) /* overflow check */ - return -ENOMEM; - - m *= 2; + bufsize = (size_t) n; } } diff -Nru systemd-252.22/src/shared/loop-util.c systemd-252.23/src/shared/loop-util.c --- systemd-252.22/src/shared/loop-util.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/shared/loop-util.c 2024-02-28 16:57:11.000000000 +0000 @@ -637,7 +637,7 @@ else direct = direct_flags != 0; if (fd < 0) { - r = -errno; + r = fd; /* Retry read-only? */ if (open_flags >= 0 || !(ERRNO_IS_PRIVILEGE(r) || r == -EROFS)) diff -Nru systemd-252.22/src/shared/machine-id-setup.c systemd-252.23/src/shared/machine-id-setup.c --- systemd-252.22/src/shared/machine-id-setup.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/shared/machine-id-setup.c 2024-02-28 16:57:11.000000000 +0000 @@ -60,7 +60,7 @@ return 0; } - } else if (IN_SET(detect_vm(), VIRTUALIZATION_KVM, VIRTUALIZATION_AMAZON, VIRTUALIZATION_QEMU)) { + } else if (IN_SET(detect_vm(), VIRTUALIZATION_KVM, VIRTUALIZATION_AMAZON, VIRTUALIZATION_QEMU, VIRTUALIZATION_XEN)) { /* If we are not running in a container, see if we are running in a VM that provides * a system UUID via the SMBIOS/DMI interfaces. Such environments include QEMU/KVM diff -Nru systemd-252.22/src/shared/seccomp-util.c systemd-252.23/src/shared/seccomp-util.c --- systemd-252.22/src/shared/seccomp-util.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/shared/seccomp-util.c 2024-02-28 16:57:11.000000000 +0000 @@ -468,6 +468,7 @@ "fchdir\0" "fchmod\0" "fchmodat\0" + "fchmodat2\0" "fcntl\0" "fcntl64\0" "fgetxattr\0" @@ -2031,7 +2032,7 @@ static int seccomp_restrict_sxid(scmp_filter_ctx seccomp, mode_t m) { /* Checks the mode_t parameter of the following system calls: * - * → chmod() + fchmod() + fchmodat() + * → chmod() + fchmod() + fchmodat() + fchmodat2() * → open() + creat() + openat() * → mkdir() + mkdirat() * → mknod() + mknodat() @@ -2074,6 +2075,28 @@ else any = true; +#if defined(__SNR_fchmodat2) + r = seccomp_rule_add_exact( + seccomp, + SCMP_ACT_ERRNO(EPERM), + SCMP_SYS(fchmodat2), + 1, + SCMP_A2(SCMP_CMP_MASKED_EQ, m, m)); +#else + /* It looks like this libseccomp does not know about fchmodat2(). + * Pretend the fchmodat2() system call is not supported at all, + * regardless of the kernel version. */ + r = seccomp_rule_add_exact( + seccomp, + SCMP_ACT_ERRNO(ENOSYS), + __NR_fchmodat2, + 0); +#endif + if (r < 0) + log_debug_errno(r, "Failed to add filter for fchmodat2: %m"); + else + any = true; + r = seccomp_rule_add_exact( seccomp, SCMP_ACT_ERRNO(EPERM), diff -Nru systemd-252.22/src/shared/utmp-wtmp.c systemd-252.23/src/shared/utmp-wtmp.c --- systemd-252.22/src/shared/utmp-wtmp.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/shared/utmp-wtmp.c 2024-02-28 16:57:11.000000000 +0000 @@ -183,6 +183,7 @@ int r; assert(id); + assert(ut_type != USER_PROCESS || user); init_timestamp(&store, 0); diff -Nru systemd-252.22/src/systemd/sd-gpt.h systemd-252.23/src/systemd/sd-gpt.h --- systemd-252.22/src/systemd/sd-gpt.h 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/systemd/sd-gpt.h 2024-02-28 16:57:11.000000000 +0000 @@ -220,7 +220,7 @@ # define SD_GPT_USR_NATIVE_VERITY SD_GPT_USR_IA64_VERITY # define SD_GPT_USR_NATIVE_VERITY_SIG SD_GPT_USR_IA64_VERITY_SIG -#elif defined(__loongarch64) +#elif defined(__loongarch_lp64) # define SD_GPT_ROOT_NATIVE SD_GPT_ROOT_LOONGARCH64 # define SD_GPT_ROOT_NATIVE_VERITY SD_GPT_ROOT_LOONGARCH64_VERITY # define SD_GPT_ROOT_NATIVE_VERITY_SIG SD_GPT_ROOT_LOONGARCH64_VERITY_SIG diff -Nru systemd-252.22/src/sysusers/sysusers.c systemd-252.23/src/sysusers/sysusers.c --- systemd-252.22/src/sysusers/sysusers.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/sysusers/sysusers.c 2024-02-28 16:57:11.000000000 +0000 @@ -1973,10 +1973,12 @@ #endif case ARG_REPLACE: - if (!path_is_absolute(optarg) || - !endswith(optarg, ".conf")) + if (!path_is_absolute(optarg)) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "The argument to --replace= must an absolute path to a config file"); + "The argument to --replace= must be an absolute path."); + if (!endswith(optarg, ".conf")) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "The argument to --replace= must have the extension '.conf'."); arg_replace = optarg; break; diff -Nru systemd-252.22/src/test/test-calendarspec.c systemd-252.23/src/test/test-calendarspec.c --- systemd-252.22/src/test/test-calendarspec.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/test/test-calendarspec.c 2024-02-28 16:57:11.000000000 +0000 @@ -260,4 +260,11 @@ assert_se(calendar_spec_from_string("*:4,30:*\n", &c) == -EINVAL); } -DEFINE_TEST_MAIN(LOG_INFO); +static int intro(void) { + /* Tests have hard-coded results that do not expect a specific timezone to be set by the caller */ + assert_se(unsetenv("TZ") >= 0); + + return EXIT_SUCCESS; +} + +DEFINE_TEST_MAIN_WITH_INTRO(LOG_INFO, intro); diff -Nru systemd-252.22/src/test/test-date.c systemd-252.23/src/test/test-date.c --- systemd-252.22/src/test/test-date.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/test/test-date.c 2024-02-28 16:57:11.000000000 +0000 @@ -62,6 +62,9 @@ } int main(int argc, char *argv[]) { + /* Tests have hard-coded results that do not expect a specific timezone to be set by the caller */ + assert_se(unsetenv("TZ") >= 0); + test_setup_logging(LOG_DEBUG); test_one("17:41"); diff -Nru systemd-252.22/src/test/test-execute.c systemd-252.23/src/test/test-execute.c --- systemd-252.22/src/test/test-execute.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/test/test-execute.c 2024-02-28 16:57:11.000000000 +0000 @@ -391,7 +391,7 @@ #elif defined(__i386__) test(m, "exec-personality-x86.service", 0, CLD_EXITED); -#elif defined(__loongarch64) +#elif defined(__loongarch_lp64) test(m, "exec-personality-loongarch64.service", 0, CLD_EXITED); #else log_notice("Unknown personality, skipping %s", __func__); diff -Nru systemd-252.22/src/test/test-fs-util.c systemd-252.23/src/test/test-fs-util.c --- systemd-252.22/src/test/test-fs-util.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/test/test-fs-util.c 2024-02-28 16:57:11.000000000 +0000 @@ -1068,4 +1068,42 @@ return EXIT_SUCCESS; } +TEST(readlinkat_malloc) { + _cleanup_(rm_rf_physical_and_freep) char *t = NULL; + _cleanup_close_ int tfd = -EBADF, fd = -EBADF; + _cleanup_free_ char *p = NULL, *q = NULL; + const char *expect = "hgoehogefoobar", *a; + + a = strjoina(arg_test_dir ?: "/tmp", "/readlinkat-malloc.XXXXXX"); + assert_se(mkdtemp_malloc(a, &t) >= 0); + + tfd = open(t, O_PATH|O_DIRECTORY|O_CLOEXEC); + assert_se(tfd >= 0); + + assert_se(symlinkat(expect, tfd, "linkname") >= 0); + + assert_se(readlinkat_malloc(tfd, "linkname", &p) >= 0); + assert_se(streq(p, expect)); + p = mfree(p); + + fd = openat(tfd, "linkname", O_PATH | O_NOFOLLOW | O_CLOEXEC); + assert_se(fd >= 0); + assert_se(readlinkat_malloc(fd, NULL, &p) >= 0); + assert_se(streq(p, expect)); + p = mfree(p); + assert_se(readlinkat_malloc(fd, "", &p) >= 0); + assert_se(streq(p, expect)); + p = mfree(p); + fd = safe_close(fd); + + assert_se(q = path_join(t, "linkname")); + assert_se(readlinkat_malloc(AT_FDCWD, q, &p) >= 0); + assert_se(streq(p, expect)); + p = mfree(p); + assert_se(readlinkat_malloc(INT_MAX, q, &p) >= 0); + assert_se(streq(p, expect)); + p = mfree(p); + q = mfree(q); +} + DEFINE_TEST_MAIN_WITH_INTRO(LOG_INFO, intro); diff -Nru systemd-252.22/src/test/test-namespace.c systemd-252.23/src/test/test-namespace.c --- systemd-252.22/src/test/test-namespace.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/test/test-namespace.c 2024-02-28 16:57:11.000000000 +0000 @@ -94,7 +94,7 @@ return; } - assert_se(socketpair(AF_UNIX, SOCK_DGRAM, 0, s) >= 0); + assert_se(socketpair(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0, s) >= 0); pid1 = fork(); assert_se(pid1 >= 0); diff -Nru systemd-252.22/src/test/test-nss-hosts.c systemd-252.23/src/test/test-nss-hosts.c --- systemd-252.22/src/test/test-nss-hosts.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/test/test-nss-hosts.c 2024-02-28 16:57:11.000000000 +0000 @@ -451,7 +451,11 @@ } else { _cleanup_free_ char *hostname = NULL; assert_se(hostname = gethostname_malloc()); - assert_se(names = strv_new("localhost", "_gateway", "_outbound", "foo_no_such_host", hostname)); + assert_se(names = strv_new("localhost", + "_gateway", + "_outbound", + hostname, + slow_tests_enabled() ? "foo_no_such_host" : NULL)); n = make_addresses(&addrs); assert_se(n >= 0); diff -Nru systemd-252.22/src/test/test-seccomp.c systemd-252.23/src/test/test-seccomp.c --- systemd-252.22/src/test/test-seccomp.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/test/test-seccomp.c 2024-02-28 16:57:11.000000000 +0000 @@ -21,6 +21,7 @@ #include "macro.h" #include "memory-util.h" #include "missing_sched.h" +#include "missing_syscall_def.h" #include "nsflags.h" #include "nulstr-util.h" #include "process-util.h" @@ -1003,6 +1004,23 @@ #endif } +static int try_fchmodat2(int dirfd, const char *path, int flags, mode_t mode) { + /* glibc does not provide a direct wrapper for fchmodat2(). Let's hence define our own wrapper for + * testing purposes that calls the real syscall, on architectures and in environments where + * SYS_fchmodat2 is defined. Otherwise, let's just fall back to the glibc fchmodat() call. */ + +#if defined __NR_fchmodat2 && __NR_fchmodat2 >= 0 + int r; + r = (int) syscall(__NR_fchmodat2, dirfd, path, flags, mode); + /* The syscall might still be unsupported by kernel or libseccomp. */ + if (r < 0 && errno == ENOSYS) + return fchmodat(dirfd, path, flags, mode); + return r; +#else + return fchmodat(dirfd, path, flags, mode); +#endif +} + TEST(restrict_suid_sgid) { pid_t pid; @@ -1044,6 +1062,11 @@ assert_se(fchmodat(AT_FDCWD, path, 0755 | S_ISGID | S_ISUID, 0) >= 0); assert_se(fchmodat(AT_FDCWD, path, 0755, 0) >= 0); + assert_se(try_fchmodat2(AT_FDCWD, path, 0755 | S_ISUID, 0) >= 0); + assert_se(try_fchmodat2(AT_FDCWD, path, 0755 | S_ISGID, 0) >= 0); + assert_se(try_fchmodat2(AT_FDCWD, path, 0755 | S_ISGID | S_ISUID, 0) >= 0); + assert_se(try_fchmodat2(AT_FDCWD, path, 0755, 0) >= 0); + k = real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID); k = safe_close(k); assert_se(unlink(z) >= 0); @@ -1145,6 +1168,11 @@ assert_se(fchmodat(AT_FDCWD, path, 0755 | S_ISGID | S_ISUID, 0) < 0 && errno == EPERM); assert_se(fchmodat(AT_FDCWD, path, 0755, 0) >= 0); + assert_se(try_fchmodat2(AT_FDCWD, path, 0755 | S_ISUID, 0) < 0 && errno == EPERM); + assert_se(try_fchmodat2(AT_FDCWD, path, 0755 | S_ISGID, 0) < 0 && errno == EPERM); + assert_se(try_fchmodat2(AT_FDCWD, path, 0755 | S_ISGID | S_ISUID, 0) < 0 && errno == EPERM); + assert_se(try_fchmodat2(AT_FDCWD, path, 0755, 0) >= 0); + assert_se(real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID) < 0 && errno == EPERM); assert_se(real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISGID) < 0 && errno == EPERM); assert_se(real_open(z, O_CREAT|O_RDWR|O_CLOEXEC|O_EXCL, 0644 | S_ISUID | S_ISGID) < 0 && errno == EPERM); diff -Nru systemd-252.22/src/test/test-time-util.c systemd-252.23/src/test/test-time-util.c --- systemd-252.22/src/test/test-time-util.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/test/test-time-util.c 2024-02-28 16:57:11.000000000 +0000 @@ -616,6 +616,9 @@ } static int intro(void) { + /* Tests have hard-coded results that do not expect a specific timezone to be set by the caller */ + assert_se(unsetenv("TZ") >= 0); + log_info("realtime=" USEC_FMT "\n" "monotonic=" USEC_FMT "\n" "boottime=" USEC_FMT "\n", diff -Nru systemd-252.22/src/timesync/timesyncd-manager.c systemd-252.23/src/timesync/timesyncd-manager.c --- systemd-252.22/src/timesync/timesyncd-manager.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/timesync/timesyncd-manager.c 2024-02-28 16:57:11.000000000 +0000 @@ -25,6 +25,7 @@ #include "network-util.h" #include "ratelimit.h" #include "resolve-private.h" +#include "random-util.h" #include "socket-util.h" #include "string-util.h" #include "strv.h" @@ -77,13 +78,6 @@ return ts->tv_sec + (1.0e-9 * ts->tv_nsec); } -static uint32_t graceful_add_offset_1900_1970(time_t t) { - /* Adds OFFSET_1900_1970 to t and returns it as 32bit value. This is handles overflows - * gracefully in a deterministic and well-defined way by cutting off the top bits. */ - uint64_t a = (uint64_t) t + OFFSET_1900_1970; - return (uint32_t) (a & UINT64_C(0xFFFFFFFF)); -} - static int manager_timeout(sd_event_source *source, usec_t usec, void *userdata) { _cleanup_free_ char *pretty = NULL; Manager *m = ASSERT_PTR(userdata); @@ -125,20 +119,22 @@ } /* - * Set transmit timestamp, remember it; the server will send that back - * as the origin timestamp and we have an indication that this is the - * matching answer to our request. - * - * The actual value does not matter, We do not care about the correct - * NTP UINT_MAX fraction; we just pass the plain nanosecond value. + * Generate a random number as transmit timestamp, to ensure we get + * a full 64 bits of entropy to make it hard for off-path attackers + * to inject random time to us. */ - assert_se(clock_gettime(CLOCK_BOOTTIME, &m->trans_time_mon) >= 0); - assert_se(clock_gettime(CLOCK_REALTIME, &m->trans_time) >= 0); - ntpmsg.trans_time.sec = htobe32(graceful_add_offset_1900_1970(m->trans_time.tv_sec)); - ntpmsg.trans_time.frac = htobe32(m->trans_time.tv_nsec); + random_bytes(&m->request_nonce, sizeof(m->request_nonce)); + ntpmsg.trans_time = m->request_nonce; server_address_pretty(m->current_server_address, &pretty); + /* + * Record the transmit timestamp. This should be as close as possible to + * the send-to to ensure the timestamp is reasonably accurate + */ + assert_se(clock_gettime(CLOCK_BOOTTIME, &m->trans_time_mon) >= 0); + assert_se(clock_gettime(CLOCK_REALTIME, &m->trans_time) >= 0); + len = sendto(m->server_socket, &ntpmsg, sizeof(ntpmsg), MSG_DONTWAIT, &m->current_server_address->sockaddr.sa, m->current_server_address->socklen); if (len == sizeof(ntpmsg)) { m->pending = true; @@ -456,9 +452,8 @@ m->missed_replies = 0; - /* check our "time cookie" (we just stored nanoseconds in the fraction field) */ - if (be32toh(ntpmsg.origin_time.sec) != graceful_add_offset_1900_1970(m->trans_time.tv_sec) || - be32toh(ntpmsg.origin_time.frac) != (unsigned long) m->trans_time.tv_nsec) { + /* check the transmit request nonce was properly returned in the origin_time field */ + if (ntpmsg.origin_time.sec != m->request_nonce.sec || ntpmsg.origin_time.frac != m->request_nonce.frac) { log_debug("Invalid reply; not our transmit time. Ignoring."); return 0; } diff -Nru systemd-252.22/src/timesync/timesyncd-manager.h systemd-252.23/src/timesync/timesyncd-manager.h --- systemd-252.22/src/timesync/timesyncd-manager.h 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/timesync/timesyncd-manager.h 2024-02-28 16:57:11.000000000 +0000 @@ -71,6 +71,7 @@ /* last sent packet */ struct timespec trans_time_mon; struct timespec trans_time; + struct ntp_ts request_nonce; usec_t retry_interval; usec_t connection_retry_usec; bool pending; diff -Nru systemd-252.22/src/tmpfiles/tmpfiles.c systemd-252.23/src/tmpfiles/tmpfiles.c --- systemd-252.22/src/tmpfiles/tmpfiles.c 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/src/tmpfiles/tmpfiles.c 2024-02-28 16:57:11.000000000 +0000 @@ -3809,10 +3809,12 @@ break; case ARG_REPLACE: - if (!path_is_absolute(optarg) || - !endswith(optarg, ".conf")) + if (!path_is_absolute(optarg)) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "The argument to --replace= must an absolute path to a config file"); + "The argument to --replace= must be an absolute path."); + if (!endswith(optarg, ".conf")) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "The argument to --replace= must have the extension '.conf'."); arg_replace = optarg; break; diff -Nru systemd-252.22/test/TEST-24-CRYPTSETUP/test.sh systemd-252.23/test/TEST-24-CRYPTSETUP/test.sh --- systemd-252.22/test/TEST-24-CRYPTSETUP/test.sh 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/test/TEST-24-CRYPTSETUP/test.sh 2024-02-28 16:57:11.000000000 +0000 @@ -70,9 +70,10 @@ /dev/mapper/$DM_NAME /var ext4 defaults 0 1 EOF - # Forward journal messages to the console, so we have something - # to investigate even if we fail to mount the encrypted /var - echo ForwardToConsole=yes >> "$initdir/etc/systemd/journald.conf" + # Forward journal messages to the console, so we have something to investigate even if we fail to mount + # the encrypted /var + mkdir "$initdir/etc/systemd/journald.conf.d/" + echo -ne "[Journal]\nForwardToConsole=yes\n" >"$initdir/etc/systemd/journald.conf.d/99-forward.conf" # If $INITRD wasn't provided explicitly, generate a custom one with dm-crypt # support diff -Nru systemd-252.22/test/TEST-55-OOMD/test.sh systemd-252.23/test/TEST-55-OOMD/test.sh --- systemd-252.22/test/TEST-55-OOMD/test.sh 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/test/TEST-55-OOMD/test.sh 2024-02-28 16:57:11.000000000 +0000 @@ -12,19 +12,16 @@ . "${TEST_BASE_DIR:?}/test-functions" test_append_files() { - # Create a swap file - ( - image_install mkswap swapon swapoff stress + local workspace="${1:?}" - dd if=/dev/zero of="${initdir:?}/swapfile" bs=1M count=48 - chmod 0600 "${initdir:?}/swapfile" + image_install mkswap swapon swapoff stress + image_install -o btrfs - mkdir -p "${initdir:?}/etc/systemd/system/init.scope.d/" - cat >>"${initdir:?}/etc/systemd/system/init.scope.d/test-55-oomd.conf" <"${workspace:?}/etc/systemd/system/init.scope.d/test-55-oomd.conf" </dev/null && \ - [[ "$(meson configure "${BUILD_DIR:?}" | grep install-tests | awk '{ print $2 }')" != "true" ]]; then + if ! get_bool "$NO_BUILD" && \ + get_bool "${TEST_REQUIRE_INSTALL_TESTS:?}" && \ + command -v meson >/dev/null && \ + [[ "$(meson configure "${BUILD_DIR:?}" | grep install-tests | awk '{ print $2 }')" != "true" ]]; then dfatal "$BUILD_DIR needs to be built with -Dinstall-tests=true" exit 1 fi diff -Nru systemd-252.22/test/test-shutdown.py systemd-252.23/test/test-shutdown.py --- systemd-252.22/test/test-shutdown.py 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/test/test-shutdown.py 2024-02-28 16:57:11.000000000 +0000 @@ -4,6 +4,7 @@ import argparse import logging +import signal import sys import pexpect @@ -90,7 +91,9 @@ except Exception as e: logger.error(e) logger.info("killing child pid %d", console.pid) - console.terminate(force=True) + + # Ask systemd-nspawn to stop and release the container's resources properly. + console.kill(signal.SIGTERM) return ret diff -Nru systemd-252.22/test/test-sysusers.sh.in systemd-252.23/test/test-sysusers.sh.in --- systemd-252.22/test/test-sysusers.sh.in 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/test/test-sysusers.sh.in 2024-02-28 16:57:11.000000000 +0000 @@ -152,7 +152,7 @@ echo "*** Running test $f" prepare_testdir ${f%.input} cp $f $TESTDIR/usr/lib/sysusers.d/test.conf - $SYSUSERS --root=$TESTDIR 2>&1 | tail -n1 | sed -r 's/^[^:]+:[^:]+://' >$TESTDIR/err + SYSTEMD_LOG_LEVEL=info $SYSUSERS --root=$TESTDIR 2>&1 | tail -n1 | sed -r 's/^[^:]+:[^:]+://' >$TESTDIR/err if ! diff -u $TESTDIR/err ${f%.*}.expected-err; then echo "**** Unexpected error output for $f" cat $TESTDIR/err diff -Nru systemd-252.22/test/units/testsuite-23.utmp.sh systemd-252.23/test/units/testsuite-23.utmp.sh --- systemd-252.22/test/units/testsuite-23.utmp.sh 1970-01-01 00:00:00.000000000 +0000 +++ systemd-252.23/test/units/testsuite-23.utmp.sh 2024-02-28 16:57:11.000000000 +0000 @@ -0,0 +1,22 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: LGPL-2.1-or-later +# -*- mode: shell-script; indent-tabs-mode: nil; sh-basic-offset: 4; -*- +# ex: ts=8 sw=4 sts=4 et filetype=sh + +set -eux +set -o pipefail + +# shellcheck source=test/units/util.sh +. "$(dirname "$0")"/util.sh + +USER="test-23-utmp" + +cleanup() { + userdel "$USER" +} + +trap cleanup EXIT +useradd "$USER" + +assert_eq "$(systemd-run -qP -p UtmpIdentifier=test -p UtmpMode=user -p User=$USER whoami)" "$USER" +assert_eq "$(systemd-run -qP -p UtmpIdentifier=test -p UtmpMode=user whoami)" "$(whoami)" diff -Nru systemd-252.22/test/units/testsuite-43.sh systemd-252.23/test/units/testsuite-43.sh --- systemd-252.22/test/units/testsuite-43.sh 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/test/units/testsuite-43.sh 2024-02-28 16:57:11.000000000 +0000 @@ -3,6 +3,11 @@ set -eux set -o pipefail +if [[ "$(sysctl -ne kernel.apparmor_restrict_unprivileged_userns)" -eq 1 ]]; then + echo "Cannot create unprivileged user namespaces" >/skipped + exit 0 +fi + systemd-analyze log-level debug runas() { diff -Nru systemd-252.22/test/units/testsuite-55.sh systemd-252.23/test/units/testsuite-55.sh --- systemd-252.22/test/units/testsuite-55.sh 2024-01-26 21:35:39.000000000 +0000 +++ systemd-252.23/test/units/testsuite-55.sh 2024-02-28 16:57:11.000000000 +0000 @@ -10,15 +10,9 @@ # Loose checks to ensure the environment has the necessary features for systemd-oomd [[ -e /proc/pressure ]] || echo "no PSI" >>/skipped -cgroup_type="$(stat -fc %T /sys/fs/cgroup/)" -if [[ "$cgroup_type" != *"cgroup2"* ]] && [[ "$cgroup_type" != *"0x63677270"* ]]; then - echo "no cgroup2" >>/skipped -fi -if [ ! -f /usr/lib/systemd/systemd-oomd ] && [ ! -f /lib/systemd/systemd-oomd ]; then - echo "no oomd" >>/skipped -fi - -if [[ -e /skipped ]]; then +[[ "$(get_cgroup_hierarchy)" == "unified" ]] || echo "no cgroupsv2" >>/skipped +[[ -x /usr/lib/systemd/systemd-oomd ]] || echo "no oomd" >>/skipped +if [[ -s /skipped ]]; then exit 0 fi @@ -26,7 +20,14 @@ # Activate swap file if we are in a VM if systemd-detect-virt --vm --quiet; then - mkswap /swapfile + if [[ "$(findmnt -n -o FSTYPE /)" == btrfs ]]; then + btrfs filesystem mkswapfile -s 64M /swapfile + else + dd if=/dev/zero of=/swapfile bs=1M count=64 + chmod 0600 /swapfile + mkswap /swapfile + fi + swapon /swapfile swapon --show fi @@ -72,27 +73,16 @@ systemctl start testsuite-55-testbloat.service # Verify systemd-oomd is monitoring the expected units -# Try to avoid racing the oomctl output check by checking in a loop with a timeout -oomctl_output=$(oomctl) -timeout="$(date -ud "1 minutes" +%s)" -while [[ $(date -u +%s) -le $timeout ]]; do - if grep "/testsuite-55-workload.slice" <<< "$oomctl_output"; then - break - fi - oomctl_output=$(oomctl) - sleep 1 -done - -grep "/testsuite-55-workload.slice" <<< "$oomctl_output" -grep "20.00%" <<< "$oomctl_output" -grep "Default Memory Pressure Duration: 2s" <<< "$oomctl_output" +timeout 1m bash -xec 'until oomctl | grep "/testsuite-55-workload.slice"; do sleep 1; done' +oomctl | grep "/testsuite-55-workload.slice" +oomctl | grep "20.00%" +oomctl | grep "Default Memory Pressure Duration: 2s" systemctl status testsuite-55-testchill.service # systemd-oomd watches for elevated pressure for 2 seconds before acting. # It can take time to build up pressure so either wait 2 minutes or for the service to fail. -timeout="$(date -ud "2 minutes" +%s)" -while [[ $(date -u +%s) -le $timeout ]]; do +for _ in {0..59}; do if ! systemctl status testsuite-55-testbloat.service; then break fi @@ -105,32 +95,23 @@ if ! systemctl status testsuite-55-testchill.service; then exit 24; fi # Make sure we also work correctly on user units. +loginctl enable-linger testuser systemctl start --machine "testuser@.host" --user testsuite-55-testchill.service systemctl start --machine "testuser@.host" --user testsuite-55-testbloat.service # Verify systemd-oomd is monitoring the expected units # Try to avoid racing the oomctl output check by checking in a loop with a timeout -oomctl_output=$(oomctl) -timeout="$(date -ud "1 minutes" +%s)" -while [[ $(date -u +%s) -le $timeout ]]; do - if grep -E "/user.slice.*/testsuite-55-workload.slice" <<< "$oomctl_output"; then - break - fi - oomctl_output=$(oomctl) - sleep 1 -done - -grep -E "/user.slice.*/testsuite-55-workload.slice" <<< "$oomctl_output" -grep "20.00%" <<< "$oomctl_output" -grep "Default Memory Pressure Duration: 2s" <<< "$oomctl_output" +timeout 1m bash -xec 'until oomctl | grep "/testsuite-55-workload.slice"; do sleep 1; done' +oomctl | grep -E "/user.slice.*/testsuite-55-workload.slice" +oomctl | grep "20.00%" +oomctl | grep "Default Memory Pressure Duration: 2s" systemctl --machine "testuser@.host" --user status testsuite-55-testchill.service # systemd-oomd watches for elevated pressure for 2 seconds before acting. # It can take time to build up pressure so either wait 2 minutes or for the service to fail. -timeout="$(date -ud "2 minutes" +%s)" -while [[ $(date -u +%s) -le $timeout ]]; do +for _ in {0..59}; do if ! systemctl --machine "testuser@.host" --user status testsuite-55-testbloat.service; then break fi @@ -142,6 +123,8 @@ if systemctl --machine "testuser@.host" --user status testsuite-55-testbloat.service; then exit 42; fi if ! systemctl --machine "testuser@.host" --user status testsuite-55-testchill.service; then exit 24; fi +loginctl disable-linger testuser + # only run this portion of the test if we can set xattrs if setfattr -n user.xattr_test -v 1 /sys/fs/cgroup/; then sleep 120 # wait for systemd-oomd kill cool down and elevated memory pressure to come down @@ -157,8 +140,7 @@ systemctl start testsuite-55-testmunch.service systemctl start testsuite-55-testbloat.service - timeout="$(date -ud "2 minutes" +%s)" - while [[ "$(date -u +%s)" -le "$timeout" ]]; do + for _ in {0..59}; do if ! systemctl status testsuite-55-testmunch.service; then break fi