Version in base suite: 252.22-1~deb12u1 Version in overlay suite: 252.23-1~deb12u1 Base version: systemd_252.23-1~deb12u1 Target version: systemd_252.24-1~deb12u1 Base file: /srv/ftp-master.debian.org/ftp/pool/main/s/systemd/systemd_252.23-1~deb12u1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/s/systemd/systemd_252.24-1~deb12u1.dsc debian/changelog | 7 debian/patches/debian/Revert-core-set-RLIMIT_CORE-to-unlimited-by-default.patch | 2 debian/patches/debian/fsckd-daemon-for-inter-fsckd-communication.patch | 4 debian/patches/p11kit-switch-to-dlopen.patch | 4 debian/salsa-ci.yml | 6 man/common-variables.xml | 8 man/custom-html.xsl | 6 man/daemon.xml | 2 man/event-quick-child.c | 2 man/hwdb-usb-device.c | 6 man/org.freedesktop.resolve1.xml | 39 +- man/path-documents.c | 2 man/portablectl.xml | 4 man/sd_bus_error-example.c | 2 man/sd_event_add_io.xml | 22 - man/sd_journal_get_cursor.xml | 15 man/sd_journal_seek_head.xml | 10 man/systemctl.xml | 68 ++- man/systemd-bless-boot.service.xml | 2 man/systemd-journald.service.xml | 16 man/systemd-socket-proxyd.xml | 5 man/systemd-timedated.service.xml | 4 man/systemd.exec.xml | 23 - man/systemd.resource-control.xml | 16 man/systemd.socket.xml | 2 meson.build | 1 shell-completion/zsh/_journalctl | 6 shell-completion/zsh/_udevadm | 2 src/backlight/backlight.c | 4 src/basic/env-util.c | 31 + src/basic/env-util.h | 2 src/basic/filesystems-gperf.gperf | 1 src/basic/hashmap.h | 2 src/basic/meson.build | 2 src/basic/missing_magic.h | 5 src/basic/virt.c | 1 src/boot/efi/boot.c | 6 src/boot/efi/cpio.c | 2 src/busctl/busctl.c | 9 src/core/bpf-socket-bind.c | 9 src/core/bpf/socket_bind/socket-bind-api.bpf.h | 7 src/core/bpf/socket_bind/socket-bind.bpf.c | 3 src/core/dynamic-user.c | 4 src/core/main.c | 2 src/core/mount.c | 22 - src/core/service.c | 12 src/journal-remote/journal-gatewayd.c | 1 src/journal-remote/journal-remote-main.c | 22 - src/journal-remote/journal-remote.c | 6 src/journal-remote/journal-remote.h | 2 src/journal-remote/journal-upload.c | 40 -- src/journal-remote/journal-upload.h | 1 src/journal/cat.c | 1 src/journal/journalctl.c | 2 src/libsystemd/sd-bus/bus-error.c | 6 src/libsystemd/sd-device/device-private.h | 5 src/libsystemd/sd-device/sd-device.c | 4 src/libsystemd/sd-event/sd-event.c | 19 src/libsystemd/sd-event/test-event.c | 18 src/libsystemd/sd-journal/journal-verify.c | 2 src/libsystemd/sd-journal/sd-journal.c | 2 src/resolve/resolved-bus.c | 10 src/resolve/resolved-dns-answer.c | 22 - src/resolve/resolved-dns-answer.h | 17 src/resolve/resolved-dns-packet.c | 7 src/resolve/resolved-dns-query.c | 27 + src/resolve/resolved-dns-rr.c | 17 src/resolve/resolved-dns-rr.h | 1 src/resolve/resolved-dns-scope.c | 34 - src/resolve/resolved-dns-scope.h | 1 src/resolve/resolved-dns-stream.c | 41 ++ src/resolve/resolved-dns-stream.h | 1 src/resolve/resolved-dns-stub.c | 10 src/resolve/resolved-dns-transaction.c | 193 +++++----- src/resolve/resolved-dns-transaction.h | 5 src/resolve/resolved-dns-trust-anchor.c | 10 src/resolve/resolved-mdns.c | 2 src/rpm/macros.systemd.in | 1 src/shared/base-filesystem.c | 4 src/shared/blockdev-util.c | 56 ++ src/shared/bpf-dlopen.c | 4 src/shared/copy.c | 2 src/shared/dlfcn-util.c | 2 src/shared/idn-util.c | 5 src/shared/install.c | 7 src/shared/tpm2-util.c | 2 src/shared/verbs.c | 18 src/shared/watchdog.c | 16 src/systemctl/systemctl-logind.c | 2 src/systemd/sd-bus-vtable.h | 8 src/userdb/userdbctl.c | 6 src/userdb/userdbd-manager.c | 8 test/TEST-69-SHUTDOWN/test.sh | 1 test/test-network/systemd-networkd-tests.py | 1 test/test-shutdown.py | 22 - test/units/testsuite-72.sh | 9 tmpfiles.d/systemd.conf.in | 11 units/systemd-journal-upload.service.in | 2 units/systemd-modules-load.service.in | 2 99 files changed, 743 insertions(+), 385 deletions(-) diff: /srv/release.debian.org/tmp/9TGQp9GJz8/systemd-252.23/test/testdata: recursive directory loop diff -Nru systemd-252.23/debian/changelog systemd-252.24/debian/changelog --- systemd-252.23/debian/changelog 2024-02-28 17:00:53.000000000 +0000 +++ systemd-252.24/debian/changelog 2024-04-26 00:34:18.000000000 +0000 @@ -1,3 +1,10 @@ +systemd (252.24-1~deb12u1) bookworm; urgency=medium + + * New upstream version 252.24 + * Refresh patches + + -- Luca Boccassi Fri, 26 Apr 2024 01:34:18 +0100 + systemd (252.23-1~deb12u1) bookworm; urgency=medium * New upstream version 252.23 (CVE-2023-50387, CVE-2023-50868) diff -Nru systemd-252.23/debian/patches/debian/Revert-core-set-RLIMIT_CORE-to-unlimited-by-default.patch systemd-252.24/debian/patches/debian/Revert-core-set-RLIMIT_CORE-to-unlimited-by-default.patch --- systemd-252.23/debian/patches/debian/Revert-core-set-RLIMIT_CORE-to-unlimited-by-default.patch 2024-02-28 17:00:53.000000000 +0000 +++ systemd-252.24/debian/patches/debian/Revert-core-set-RLIMIT_CORE-to-unlimited-by-default.patch 2024-04-26 00:34:02.000000000 +0000 @@ -19,7 +19,7 @@ 2 files changed, 1 insertion(+), 21 deletions(-) diff --git a/src/core/main.c b/src/core/main.c -index 1c4b464..e84e7dd 100644 +index a0c7b42..914876e 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1650,24 +1650,6 @@ static void cmdline_take_random_seed(void) { diff -Nru systemd-252.23/debian/patches/debian/fsckd-daemon-for-inter-fsckd-communication.patch systemd-252.24/debian/patches/debian/fsckd-daemon-for-inter-fsckd-communication.patch --- systemd-252.23/debian/patches/debian/fsckd-daemon-for-inter-fsckd-communication.patch 2024-02-28 17:00:53.000000000 +0000 +++ systemd-252.24/debian/patches/debian/fsckd-daemon-for-inter-fsckd-communication.patch 2024-04-26 00:34:02.000000000 +0000 @@ -239,10 +239,10 @@ + + diff --git a/meson.build b/meson.build -index e707742..6330645 100644 +index 703ee3a..07963ce 100644 --- a/meson.build +++ b/meson.build -@@ -3368,6 +3368,15 @@ executable( +@@ -3369,6 +3369,15 @@ executable( install : true, install_dir : rootlibexecdir) diff -Nru systemd-252.23/debian/patches/p11kit-switch-to-dlopen.patch systemd-252.24/debian/patches/p11kit-switch-to-dlopen.patch --- systemd-252.23/debian/patches/p11kit-switch-to-dlopen.patch 2024-02-28 17:00:53.000000000 +0000 +++ systemd-252.24/debian/patches/p11kit-switch-to-dlopen.patch 2024-04-26 00:34:02.000000000 +0000 @@ -13,10 +13,10 @@ 7 files changed, 202 insertions(+), 60 deletions(-) diff --git a/meson.build b/meson.build -index afcb4a7..e707742 100644 +index aea27dc..703ee3a 100644 --- a/meson.build +++ b/meson.build -@@ -1462,8 +1462,10 @@ if want_p11kit != 'false' and not skip_deps +@@ -1463,8 +1463,10 @@ if want_p11kit != 'false' and not skip_deps version : '>= 0.23.3', required : want_p11kit == 'true') have = libp11kit.found() diff -Nru systemd-252.23/debian/salsa-ci.yml systemd-252.24/debian/salsa-ci.yml --- systemd-252.23/debian/salsa-ci.yml 2024-02-28 17:00:53.000000000 +0000 +++ systemd-252.24/debian/salsa-ci.yml 2024-04-26 00:34:18.000000000 +0000 @@ -10,3 +10,9 @@ SALSA_CI_DISABLE_PIUPARTS: 1 RELEASE: 'bookworm' SALSA_CI_LINTIAN_SUPPRESS_TAGS: "bad-distribution-in-changes-file" + # The following jobs all run on unstable, and cannot work because they expect + # overrides, compiler flags, dependencies, etc to work as in unstable, but this + # is a stable branch + SALSA_CI_DISABLE_LINTIAN: 1 + SALSA_CI_DISABLE_BLHC: 1 + SALSA_CI_DISABLE_REPROTEST: 1 diff -Nru systemd-252.23/man/common-variables.xml systemd-252.24/man/common-variables.xml --- systemd-252.23/man/common-variables.xml 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/man/common-variables.xml 2024-04-26 00:30:13.000000000 +0000 @@ -129,6 +129,9 @@ + Note that setting the regular $LESS environment variable has no effect + for less invocations by systemd tools. + See less1 for more discussion. @@ -138,7 +141,10 @@ $SYSTEMD_LESSCHARSET Override the charset passed to less (by default utf-8, if - the invoking terminal is determined to be UTF-8 compatible). + the invoking terminal is determined to be UTF-8 compatible). + + Note that setting the regular $LESSCHARSET environment variable has no effect + for less invocations by systemd tools. diff -Nru systemd-252.23/man/custom-html.xsl systemd-252.24/man/custom-html.xsl --- systemd-252.23/man/custom-html.xsl 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/man/custom-html.xsl 2024-04-26 00:30:13.000000000 +0000 @@ -81,13 +81,11 @@ - https://www.archlinux.org/ - - / + https://man.archlinux.org/man/ . - .html + .en.html diff -Nru systemd-252.23/man/daemon.xml systemd-252.24/man/daemon.xml --- systemd-252.23/man/daemon.xml 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/man/daemon.xml 2024-04-26 00:30:13.000000000 +0000 @@ -75,7 +75,7 @@ create an independent session. In the child, call fork() again, to ensure that the daemon can - never re-acquire a terminal again. (This relevant if the program — and all its dependencies — does + never re-acquire a terminal again. (This is relevant if the program — and all its dependencies — does not carefully specify `O_NOCTTY` on each and every single `open()` call that might potentially open a TTY device node.) diff -Nru systemd-252.23/man/event-quick-child.c systemd-252.24/man/event-quick-child.c --- systemd-252.23/man/event-quick-child.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/man/event-quick-child.c 2024-04-26 00:30:13.000000000 +0000 @@ -3,7 +3,7 @@ #include #include #include -#include +#include int main(int argc, char **argv) { pid_t pid = fork(); diff -Nru systemd-252.23/man/hwdb-usb-device.c systemd-252.24/man/hwdb-usb-device.c --- systemd-252.23/man/hwdb-usb-device.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/man/hwdb-usb-device.c 2024-04-26 00:30:13.000000000 +0000 @@ -2,16 +2,16 @@ #include #include -#include +#include int print_usb_properties(uint16_t vid, uint16_t pid) { - char match[STRLEN("usb:vp") + DECIMAL_STR_MAX(uint16_t) * 2]; + char match[128]; sd_hwdb *hwdb; const char *key, *value; int r; /* Match this USB vendor and product ID combination */ - xsprintf(match, "usb:v%04Xp%04X", vid, pid); + snprintf(match, sizeof match, "usb:v%04Xp%04X", vid, pid); r = sd_hwdb_new(&hwdb); if (r < 0) diff -Nru systemd-252.23/man/org.freedesktop.resolve1.xml systemd-252.24/man/org.freedesktop.resolve1.xml --- systemd-252.23/man/org.freedesktop.resolve1.xml 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/man/org.freedesktop.resolve1.xml 2024-04-26 00:30:13.000000000 +0000 @@ -156,16 +156,6 @@ }; - - - - - - - - - - @@ -433,6 +423,30 @@ The RevertLink() method may be used to revert all per-link settings described above to the defaults. + The FlushCaches() flushes all resource record caches maintained by the + resolver, and ensures that any subsequent lookups re-request their responses from their sources. + + The ResetServerFeatures() flushes any feature information learned about + remote DNS servers. This ensures that subsequent lookups will be initially attempted at the highest DNS + protocol feature level again, possibly requiring a (potentially slow) downgrade cycle to recognize the + supported feature level again. + + The RegisterService() method may be used to register a DNS-SD service on the + host. This functionality is closely related to the functionality provided by + systemd.dnssd5 + files. It takes a server identifier string as first parameter (this is jus a local identifier, and + should be chosen so that it neither collides with the basename of *.dnssd files + nor with names chosen by other IPC clients). It also takes a name template string for the DNS-SD + service name visible on the network. This string is subject to specifier expansation, as documented for + the Name= setting in *.dnssd files. It also takes a service + type string containing the DNS-SD service type, as well as an IP port, a priority/weight pair for the + DNS-SD SRV record. Finally, it takes an array of TXT record data. It returns an object path which may be + used as handle to the registered service. + + The UnregisterService() method undoes the effect of + RegisterService() and deletes a DNS-SD service previously created via IPC + again. + The Flags Parameter @@ -634,6 +648,9 @@ enabled. Possible values are yes (enabled), no (disabled), udp (only the UDP listener is enabled), and tcp (only the TCP listener is enabled). + + The DNSSECNegativeTrustAnchors property contains a list of recognized DNSSEC + negative trust anchors and contains a list of domains. @@ -688,8 +705,6 @@ }; - - diff -Nru systemd-252.23/man/path-documents.c systemd-252.24/man/path-documents.c --- systemd-252.23/man/path-documents.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/man/path-documents.c 2024-04-26 00:30:13.000000000 +0000 @@ -2,7 +2,7 @@ #include #include -#include +#include int main(void) { int r; diff -Nru systemd-252.23/man/portablectl.xml systemd-252.24/man/portablectl.xml --- systemd-252.23/man/portablectl.xml 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/man/portablectl.xml 2024-04-26 00:30:13.000000000 +0000 @@ -45,12 +45,12 @@ within the file system context of the image. Portable service images are an efficient way to bundle multiple related services and other units together, - and transfer them as a whole between systems. When these images are attached the local system the contained units + and transfer them as a whole between systems. When these images are attached to the local system, the contained units may run in most ways like regular system-provided units, either with full privileges or inside strict sandboxing, depending on the selected configuration. For more details, see Portable Services. - Specifically portable service images may be of the following kind: + Portable service images may be of the following kinds: Directory trees containing an OS, including the top-level directories /usr/, diff -Nru systemd-252.23/man/sd_bus_error-example.c systemd-252.24/man/sd_bus_error-example.c --- systemd-252.23/man/sd_bus_error-example.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/man/sd_bus_error-example.c 2024-04-26 00:30:13.000000000 +0000 @@ -3,7 +3,7 @@ #include #include #include -#include +#include int writer_with_negative_errno_return(int fd, sd_bus_error *error) { const char *message = "Hello, World!\n"; diff -Nru systemd-252.23/man/sd_event_add_io.xml systemd-252.24/man/sd_event_add_io.xml --- systemd-252.23/man/sd_event_add_io.xml 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/man/sd_event_add_io.xml 2024-04-26 00:30:13.000000000 +0000 @@ -217,16 +217,20 @@ source object and returns the non-negative file descriptor or a negative error number on error (see below). - sd_event_source_set_io_fd() - changes the UNIX file descriptor of an I/O event source created - previously with sd_event_add_io(). It takes - the event source object and the new file descriptor. + sd_event_source_set_io_fd() changes the UNIX file descriptor of an I/O event + source created previously with sd_event_add_io(). It takes the event source object + and the new file descriptor. If the event source takes the ownership of the previous file descriptor, + that is, sd_event_source_set_io_fd_own() was called for the event source with a + non-zero value, then the previous file descriptor will be closed and the event source will also take the + ownership of the new file descriptor on success. - sd_event_source_set_io_fd_own() controls whether the file descriptor of the event source - shall be closed automatically when the event source is freed, i.e. whether it shall be considered 'owned' by the - event source object. By default it is not closed automatically, and the application has to do this on its own. The - b parameter is a boolean parameter: if zero, the file descriptor is not closed automatically - when the event source is freed, otherwise it is closed. + sd_event_source_set_io_fd_own() controls whether the file descriptor of the + event source shall be closed automatically when the event source is freed (or when the file descriptor + assigned to the event source is replaced by sd_event_source_set_io_fd()), i.e. + whether it shall be considered 'owned' by the event source object. By default it is not closed + automatically, and the application has to do this on its own. The b parameter is a + boolean parameter: if zero, the file descriptor is not closed automatically when the event source is + freed, otherwise it is closed. sd_event_source_get_io_fd_own() may be used to query the current setting of the file descriptor ownership boolean flag as set with sd_event_source_set_io_fd_own(). It returns diff -Nru systemd-252.23/man/sd_journal_get_cursor.xml systemd-252.24/man/sd_journal_get_cursor.xml --- systemd-252.23/man/sd_journal_get_cursor.xml 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/man/sd_journal_get_cursor.xml 2024-04-26 00:30:13.000000000 +0000 @@ -61,12 +61,6 @@ and should be freed after use with free3. - Note that sd_journal_get_cursor() will - not work before - sd_journal_next3 - (or related call) has been called at least once, in order to - position the read pointer at a valid entry. - sd_journal_test_cursor() may be used to check whether the current position in the journal matches the specified cursor. This is @@ -75,10 +69,17 @@ multiple different cursor strings, and hence string comparing cursors is not possible. Use this call to verify after an invocation of - sd_journal_seek_cursor3 + sd_journal_seek_cursor3, whether the entry being sought to was actually found in the journal or the next closest entry was used instead. + + Note that sd_journal_get_cursor() + and sd_journal_test_cursor() + will not work before + sd_journal_next3 + (or one of the other functions which move to an entry) + has been called at least once to position the read pointer at a valid entry. diff -Nru systemd-252.23/man/sd_journal_seek_head.xml systemd-252.24/man/sd_journal_seek_head.xml --- systemd-252.23/man/sd_journal_seek_head.xml 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/man/sd_journal_seek_head.xml 2024-04-26 00:30:13.000000000 +0000 @@ -82,8 +82,7 @@ string. For details on cursors, see sd_journal_get_cursor3. If no entry matching the specified cursor is found the call will seek to the next closest entry (in terms - of time) instead. To verify whether the newly selected entry actually matches the cursor, use - sd_journal_test_cursor3. + of time) instead. Note that these calls do not actually make any entry the new current entry, this needs to be done in a separate step with a subsequent @@ -97,6 +96,13 @@ used, the closest following entry will be sought to, if sd_journal_previous3 is used the closest preceding entry is sought to. + + After the seek is done, and + sd_journal_next3 + or a similar call has been made, + sd_journal_test_cursor3 + may be used to verify whether the newly selected entry actually matches the cursor. + diff -Nru systemd-252.23/man/systemctl.xml systemd-252.24/man/systemctl.xml --- systemd-252.23/man/systemctl.xml 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/man/systemctl.xml 2024-04-26 00:30:13.000000000 +0000 @@ -1176,46 +1176,64 @@ show-environment - Dump the systemd manager environment block. This is the environment - block that is passed to all processes the manager spawns. The environment - block will be dumped in straightforward form suitable for sourcing into - most shells. If no special characters or whitespace is present in the variable - values, no escaping is performed, and the assignments have the form - VARIABLE=value. If whitespace or characters which have - special meaning to the shell are present, dollar-single-quote escaping is - used, and assignments have the form VARIABLE=$'value'. - This syntax is known to be supported by - bash1, - zsh1, - ksh1, - and - busybox1's - ash1, - but not - dash1 - or - fish1. + Dump the systemd manager environment block. This is the environment block that is passed to + all processes the manager spawns. The environment block will be dumped in straightforward form + suitable for sourcing into most shells. If no special characters or whitespace is present in the + variable values, no escaping is performed, and the assignments have the form + VARIABLE=value. If whitespace or characters which have special meaning to the + shell are present, dollar-single-quote escaping is used, and assignments have the form + VARIABLE=$'value'. This syntax is known to be supported by bash1, + zsh1, + ksh1, and + busybox1's + ash1, but + not dash1 or + fish1. + + Note that this shows the effective block, i.e. the combination of + environment variables configured via configuration files, environment generators and via IPC + (i.e. via the set-environment described below). At the moment a unit process + is forked off this combined environment block will be further combined with per-unit environment + variables, which are not visible in this command. set-environment VARIABLE=VALUE - Set one or more systemd manager environment variables, as specified on the command + Set one or more service manager environment variables, as specified on the command line. This command will fail if variable names and values do not conform to the rules listed above. + + Note that this operates on an environment block separate from the environment block + configured from service manager configuration and environment generators. Whenever a process is + invoked the two blocks are combined (also incorporating any per-service environment variables), + and passed to it. The show-environment verb will show the combination of the + blocks, see above. unset-environment VARIABLE - Unset one or more systemd manager environment - variables. If only a variable name is specified, it will be - removed regardless of its value. If a variable and a value - are specified, the variable is only removed if it has the - specified value. + Unset one or more systemd manager environment variables. If only a variable name is + specified, it will be removed regardless of its value. If a variable and a value are specified, + the variable is only removed if it has the specified value. + + Note that this operates on an environment block separate from the environment block + configured from service manager configuration and environment generators. Whenever a process is + invoked the two blocks are combined (also incorporating any per-service environment variables), + and passed to it. The show-environment verb will show the combination of the + blocks, see above. Note that this means this command cannot be used to unset environment + variables defined in the service manager configuration files or via generators. diff -Nru systemd-252.23/man/systemd-bless-boot.service.xml systemd-252.24/man/systemd-bless-boot.service.xml --- systemd-252.23/man/systemd-bless-boot.service.xml 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/man/systemd-bless-boot.service.xml 2024-04-26 00:30:13.000000000 +0000 @@ -37,7 +37,7 @@ boot counting is used. Internally, the service operates based on the LoaderBootCountPath EFI variable (of the - vendor UUID 4a67b082-0a4c-41cf-b6c7-440b29bb8c4), which is passed from the boot loader to the + vendor UUID 4a67b082-0a4c-41cf-b6c7-440b29bb8c4f), which is passed from the boot loader to the OS. It contains a file system path (relative to the EFI system partition) of the Boot Loader Specification compliant boot loader entry file or unified kernel image file that was used to boot up the diff -Nru systemd-252.23/man/systemd-journald.service.xml systemd-252.24/man/systemd-journald.service.xml --- systemd-252.23/man/systemd-journald.service.xml 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/man/systemd-journald.service.xml 2024-04-26 00:30:13.000000000 +0000 @@ -236,6 +236,22 @@ + + + systemd.journald.max_level_store= + systemd.journald.max_level_syslog= + systemd.journald.max_level_kmsg= + systemd.journald.max_level_console= + systemd.journald.max_level_wall= + systemd.journald.max_level_socket= + + Controls the maximum log level of messages that are stored in the journal, forwarded + to syslog, kmsg, the console, the wall, or a socket. This kernel command line options override the + settings of the same names in the + journald.conf5 + file. + + Note that these kernel command line options are only honoured by the default namespace, see diff -Nru systemd-252.23/man/systemd-socket-proxyd.xml systemd-252.24/man/systemd-socket-proxyd.xml --- systemd-252.23/man/systemd-socket-proxyd.xml 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/man/systemd-socket-proxyd.xml 2024-04-26 00:30:13.000000000 +0000 @@ -53,6 +53,11 @@ Accept=no and an event-driven design that scales better with the number of connections. + + Note that systemd-socket-proxyd will not forward socket side channel + information, i.e. will not forward SCM_RIGHTS, SCM_CREDENTIALS, + SCM_SECURITY, SO_PEERCRED, SO_PEERPIDFD, + SO_PEERSEC, SO_PEERGROUPS and similar. Options diff -Nru systemd-252.23/man/systemd-timedated.service.xml systemd-252.24/man/systemd-timedated.service.xml --- systemd-252.23/man/systemd-timedated.service.xml 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/man/systemd-timedated.service.xml 2024-04-26 00:30:13.000000000 +0000 @@ -63,7 +63,7 @@ List of network time synchronization services - systemd-timesyncd will look for files with a .list extension + systemd-timedated will look for files with a .list extension in ntp-units.d/ directories. Each file is parsed as a list of unit names, one per line. Empty lines and lines with comments (#) are ignored. Files are read from /usr/lib/systemd/ntp-units.d/ and the corresponding directories under @@ -82,7 +82,7 @@ If the environment variable $SYSTEMD_TIMEDATED_NTP_SERVICES is set, - systemd-timesyncd will parse the contents of that variable as a colon-separated list + systemd-timedated will parse the contents of that variable as a colon-separated list of unit names. When set, this variable overrides the file-based list described above. diff -Nru systemd-252.23/man/systemd.exec.xml systemd-252.24/man/systemd.exec.xml --- systemd-252.23/man/systemd.exec.xml 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/man/systemd.exec.xml 2024-04-26 00:30:13.000000000 +0000 @@ -1240,6 +1240,11 @@ accessible to privileged processes. However, most namespacing settings, that will not work on their own in user services, will work when used in conjunction with PrivateUsers=. + Note that the various options that turn directories read-only (such as + ProtectSystem=, ReadOnlyPaths=, …) do not affect the ability for + programs to connect to and communicate with AF_UNIX sockets in these + directores. These options cannot be used to lock down access to IPC services hence. + @@ -1253,14 +1258,16 @@ mounted read-only, except for the API file system subtrees /dev/, /proc/ and /sys/ (protect these directories using PrivateDevices=, ProtectKernelTunables=, - ProtectControlGroups=). This setting ensures that any modification of the vendor-supplied - operating system (and optionally its configuration, and local mounts) is prohibited for the service. It is - recommended to enable this setting for all long-running services, unless they are involved with system updates - or need to modify the operating system in other ways. If this option is used, - ReadWritePaths= may be used to exclude specific directories from being made read-only. This - setting is implied if DynamicUser= is set. This setting cannot ensure protection in all - cases. In general it has the same limitations as ReadOnlyPaths=, see below. Defaults to - off. + ProtectControlGroups=). This setting ensures that any modification of the + vendor-supplied operating system (and optionally its configuration, and local mounts) is prohibited + for the service. It is recommended to enable this setting for all long-running services, unless they + are involved with system updates or need to modify the operating system in other ways. If this option + is used, ReadWritePaths= may be used to exclude specific directories from being + made read-only. Similar, StateDirectory=, LogsDirectory=, … and + related directory settings (see below) also exclude the specific directories from the effect of + ProtectSystem=. This setting is implied if DynamicUser= is + set. This setting cannot ensure protection in all cases. In general it has the same limitations as + ReadOnlyPaths=, see below. Defaults to off. diff -Nru systemd-252.23/man/systemd.resource-control.xml systemd-252.24/man/systemd.resource-control.xml --- systemd-252.23/man/systemd.resource-control.xml 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/man/systemd.resource-control.xml 2024-04-26 00:30:13.000000000 +0000 @@ -632,6 +632,9 @@ The system default for this setting may be controlled with DefaultIPAccounting= in systemd-system.conf5. + + Note that this functionality is currently only available for system services, not for + per-user services. @@ -828,8 +831,10 @@ SocketBindDeny=bind-rule - Allow or deny binding a socket address to a socket by matching it with the bind-rule and - applying a corresponding action if there is a match. + Configures restrictions on the ability of unit processes to invoke bind2 on a + socket. Both allow and deny rules may defined that restrict which addresses a socket may be bound + to. bind-rule describes socket properties such as address-family, transport-protocol and ip-ports. @@ -876,6 +881,13 @@ The feature is implemented with cgroup/bind4 and cgroup/bind6 cgroup-bpf hooks. + + Note that these settings apply to any bind2 + system call invocation by the unit processes, regardless in which network namespace they are + placed. Or in other words: changing the network namespace is not a suitable mechanism for escaping + these restrictions on bind(). + Examples:… # Allow binding IPv6 socket addresses with a port greater than or equal to 10000. [Service] diff -Nru systemd-252.23/man/systemd.socket.xml systemd-252.24/man/systemd.socket.xml --- systemd-252.23/man/systemd.socket.xml 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/man/systemd.socket.xml 2024-04-26 00:30:13.000000000 +0000 @@ -724,7 +724,7 @@ TCPCongestion= Takes a string value. Controls the TCP congestion algorithm used by this - socket. Should be one of westwood, veno, + socket. Should be one of westwood, reno, cubic, lp or any other available algorithm supported by the IP stack. This setting applies only to stream sockets. diff -Nru systemd-252.23/meson.build systemd-252.24/meson.build --- systemd-252.23/meson.build 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/meson.build 2024-04-26 00:30:13.000000000 +0000 @@ -240,6 +240,7 @@ conf.set_quoted('ENVIRONMENT_DIR', environmentdir) conf.set_quoted('INCLUDE_DIR', includedir) conf.set_quoted('LIBDIR', libdir) +conf.set_quoted('KERNEL_INSTALL_DIR', kernelinstalldir) conf.set_quoted('MODPROBE_DIR', modprobedir) conf.set_quoted('MODULESLOAD_DIR', modulesloaddir) conf.set_quoted('PKGSYSCONFDIR', pkgsysconfdir) diff -Nru systemd-252.23/shell-completion/zsh/_journalctl systemd-252.24/shell-completion/zsh/_journalctl --- systemd-252.23/shell-completion/zsh/_journalctl 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/shell-completion/zsh/_journalctl 2024-04-26 00:30:13.000000000 +0000 @@ -59,7 +59,7 @@ (( $+functions[_journalctl_facilities] )) || _journalctl_facilities() { local -a _journalctl_facilities - _journalctl_facilities=(kern user mail daemon auth syslog lpr news uucp cron authpriv ftp local0 local1 local2 local3 local4 local5 local6 local7) + _journalctl_facilities=(help kern user mail daemon auth syslog lpr news uucp cron authpriv ftp local0 local1 local2 local3 local4 local5 local6 local7) _describe 'possible values' _journalctl_facilities } @@ -113,10 +113,12 @@ '--facility=[Filter messages by facility]:facility:_journalctl_facilities' \ {-t+,--identifier=}'[Filter messages by syslog identifier]:identifier:_journalctl_field_values SYSLOG_IDENTIFIER' \ {-c+,--cursor=}'[Start showing entries from the specified cursor]:cursors:_journalctl_field_values __CURSORS' \ - '--cursor-file=[Show entries using cursor store in file]:file:_files' \ + '--cursor-file=[Show entries using cursor stored in file]:file:_files' \ '--after-cursor=[Start showing entries from after the specified cursor]:cursors:_journalctl_field_values __CURSORS' \ '--since=[Start showing entries on or newer than the specified date]:YYYY-MM-DD HH\:MM\:SS' \ '--until=[Stop showing entries on or older than the specified date]:YYYY-MM-DD HH\:MM\:SS' \ + {-g+,--grep=}'[Show entries with MESSAGE field matching PCRE pattern]' \ + '--case-sensitive=[Force case sensitive or insensitive matching]:boolean:(true false)' \ {-F,--field=}'[List all values a certain field takes]:Fields:_journalctl_fields' \ '--system[Show system and kernel messages]' \ '--user[Show messages from user services]' \ diff -Nru systemd-252.23/shell-completion/zsh/_udevadm systemd-252.24/shell-completion/zsh/_udevadm --- systemd-252.23/shell-completion/zsh/_udevadm 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/shell-completion/zsh/_udevadm 2024-04-26 00:30:13.000000000 +0000 @@ -155,7 +155,7 @@ 'test:test an event run' 'test-builtin:test a built-in command' 'wait:wait for devices or device symlinks being created' - 'lock:lock a block device and run a comand' + 'lock:lock a block device and run a command' ) if ((CURRENT == 1)); then diff -Nru systemd-252.23/src/backlight/backlight.c systemd-252.24/src/backlight/backlight.c --- systemd-252.23/src/backlight/backlight.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/backlight/backlight.c 2024-04-26 00:30:13.000000000 +0000 @@ -56,6 +56,10 @@ if (r < 0) return r; + r = sd_device_enumerator_allow_uninitialized(e); + if (r < 0) + return r; + r = sd_device_enumerator_add_match_subsystem(e, "pci", /* match = */ true); if (r < 0) return r; diff -Nru systemd-252.23/src/basic/env-util.c systemd-252.24/src/basic/env-util.c --- systemd-252.23/src/basic/env-util.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/basic/env-util.c 2024-04-26 00:30:13.000000000 +0000 @@ -811,8 +811,8 @@ } int setenv_systemd_exec_pid(bool update_only) { - char str[DECIMAL_STR_MAX(pid_t)]; const char *e; + int r; /* Update $SYSTEMD_EXEC_PID=pid except when '*' is set for the variable. */ @@ -823,10 +823,9 @@ if (streq_ptr(e, "*")) return 0; - xsprintf(str, PID_FMT, getpid_cached()); - - if (setenv("SYSTEMD_EXEC_PID", str, 1) < 0) - return -errno; + r = setenvf("SYSTEMD_EXEC_PID", /* overwrite= */ 1, PID_FMT, getpid_cached()); + if (r < 0) + return r; return 1; } @@ -902,3 +901,25 @@ return 1; } + +int setenvf(const char *name, bool overwrite, const char *valuef, ...) { + _cleanup_free_ char *value = NULL; + va_list ap; + int r; + + assert(name); + + if (!valuef) + return RET_NERRNO(unsetenv(name)); + + va_start(ap, valuef); + DISABLE_WARNING_FORMAT_NONLITERAL; + r = vasprintf(&value, valuef, ap); + REENABLE_WARNING; + va_end(ap); + + if (r < 0) + return -ENOMEM; + + return RET_NERRNO(setenv(name, value, overwrite)); +} diff -Nru systemd-252.23/src/basic/env-util.h systemd-252.24/src/basic/env-util.h --- systemd-252.23/src/basic/env-util.h 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/basic/env-util.h 2024-04-26 00:30:13.000000000 +0000 @@ -72,3 +72,5 @@ int getenv_path_list(const char *name, char ***ret_paths); int getenv_steal_erase(const char *name, char **ret); + +int setenvf(const char *name, bool overwrite, const char *valuef, ...) _printf_(3,4); diff -Nru systemd-252.23/src/basic/filesystems-gperf.gperf systemd-252.24/src/basic/filesystems-gperf.gperf --- systemd-252.23/src/basic/filesystems-gperf.gperf 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/basic/filesystems-gperf.gperf 2024-04-26 00:30:13.000000000 +0000 @@ -91,6 +91,7 @@ openpromfs, {OPENPROM_SUPER_MAGIC} orangefs, {ORANGEFS_DEVREQ_MAGIC} overlay, {OVERLAYFS_SUPER_MAGIC} +pidfs, {PID_FS_MAGIC} pipefs, {PIPEFS_MAGIC} ppc-cmm, {PPC_CMM_MAGIC} proc, {PROC_SUPER_MAGIC} diff -Nru systemd-252.23/src/basic/hashmap.h systemd-252.24/src/basic/hashmap.h --- systemd-252.23/src/basic/hashmap.h 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/basic/hashmap.h 2024-04-26 00:30:13.000000000 +0000 @@ -40,8 +40,8 @@ * by hashmap users, so the definition has to be here. Do not use its fields * directly. */ typedef struct { - unsigned idx; /* index of an entry to be iterated next */ const void *next_key; /* expected value of that entry's key pointer */ + unsigned idx; /* index of an entry to be iterated next */ #if ENABLE_DEBUG_HASHMAP unsigned put_count; /* hashmap's put_count recorded at start of iteration */ unsigned rem_count; /* hashmap's rem_count in previous iteration */ diff -Nru systemd-252.23/src/basic/meson.build systemd-252.24/src/basic/meson.build --- systemd-252.23/src/basic/meson.build 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/basic/meson.build 2024-04-26 00:30:13.000000000 +0000 @@ -389,7 +389,7 @@ check_filesystems = find_program('check-filesystems.sh') r = run_command([check_filesystems, cpp, files('filesystems-gperf.gperf')] + filesystem_includes, check: false) if r.returncode() != 0 - error('Unknown filesystems defined in kernel headers:\n\n' + r.stdout()) + warning('Unknown filesystems defined in kernel headers:\n\n' + r.stdout()) endif filesystems_gperf_h = custom_target( diff -Nru systemd-252.23/src/basic/missing_magic.h systemd-252.24/src/basic/missing_magic.h --- systemd-252.23/src/basic/missing_magic.h 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/basic/missing_magic.h 2024-04-26 00:30:13.000000000 +0000 @@ -128,6 +128,11 @@ #define DEVMEM_MAGIC 0x454d444d #endif +/* cb12fd8e0dabb9a1c8aef55a6a41e2c255fcdf4b (6.8) */ +#ifndef PID_FS_MAGIC +#define PID_FS_MAGIC 0x50494446 +#endif + /* Not in mainline but included in Ubuntu */ #ifndef SHIFTFS_MAGIC #define SHIFTFS_MAGIC 0x6a656a62 diff -Nru systemd-252.23/src/basic/virt.c systemd-252.24/src/basic/virt.c --- systemd-252.23/src/basic/virt.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/basic/virt.c 2024-04-26 00:30:13.000000000 +0000 @@ -178,6 +178,7 @@ { "VMW", VIRTUALIZATION_VMWARE }, { "innotek GmbH", VIRTUALIZATION_ORACLE }, { "VirtualBox", VIRTUALIZATION_ORACLE }, + { "Oracle Corporation", VIRTUALIZATION_ORACLE }, /* Detect VirtualBox on some proprietary systems via the board_vendor */ { "Xen", VIRTUALIZATION_XEN }, { "Bochs", VIRTUALIZATION_BOCHS }, { "Parallels", VIRTUALIZATION_PARALLELS }, diff -Nru systemd-252.23/src/boot/efi/boot.c systemd-252.24/src/boot/efi/boot.c --- systemd-252.23/src/boot/efi/boot.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/boot/efi/boot.c 2024-04-26 00:30:13.000000000 +0000 @@ -2305,9 +2305,9 @@ assert(ret_initrd_size); if (entry->type != LOADER_LINUX || !entry->initrd) { - ret_options = NULL; - ret_initrd = NULL; - ret_initrd_size = 0; + *ret_options = NULL; + *ret_initrd = NULL; + *ret_initrd_size = 0; return EFI_SUCCESS; } diff -Nru systemd-252.23/src/boot/efi/cpio.c systemd-252.24/src/boot/efi/cpio.c --- systemd-252.23/src/boot/efi/cpio.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/boot/efi/cpio.c 2024-04-26 00:30:13.000000000 +0000 @@ -63,7 +63,7 @@ char *a; assert(fname); - assert(contents_size || contents_size == 0); + assert(contents || contents_size == 0); assert(target_dir_prefix); assert(inode_counter); assert(cpio_buffer); diff -Nru systemd-252.23/src/busctl/busctl.c systemd-252.24/src/busctl/busctl.c --- systemd-252.23/src/busctl/busctl.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/busctl/busctl.c 2024-04-26 00:30:13.000000000 +0000 @@ -2021,6 +2021,15 @@ if (r < 0) return r; + if (!service_name_is_valid(argv[1])) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid service name: %s", argv[1]); + if (!object_path_is_valid(argv[2])) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid object path: %s", argv[2]); + if (!interface_name_is_valid(argv[3])) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid interface name: %s", argv[3]); + if (!member_name_is_valid(argv[4])) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Invalid member name: %s", argv[4]); + r = sd_bus_message_new_method_call(bus, &m, argv[1], argv[2], argv[3], argv[4]); if (r < 0) return bus_log_create_error(r); diff -Nru systemd-252.23/src/core/bpf/socket_bind/socket-bind-api.bpf.h systemd-252.24/src/core/bpf/socket_bind/socket-bind-api.bpf.h --- systemd-252.23/src/core/bpf/socket_bind/socket-bind-api.bpf.h 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/core/bpf/socket_bind/socket-bind-api.bpf.h 2024-04-26 00:30:13.000000000 +0000 @@ -7,13 +7,17 @@ */ #include +#include /* * Bind rule is matched with socket fields accessible to cgroup/bind{4,6} hook * through bpf_sock_addr struct. - * 'address_family' is expected to be one of AF_UNSPEC, AF_INET or AF_INET6. + * 'address_family' is expected to be one of AF_UNSPEC, AF_INET, AF_INET6 or the + * magic SOCKET_BIND_RULE_AF_MATCH_NOTHING. * Matching by family is bypassed for rules with AF_UNSPEC set, which makes the * rest of a rule applicable for both IPv4 and IPv6 addresses. + * If SOCKET_BIND_RULE_AF_MATCH_NOTHING is set the rule fails unconditionally + * and other checks are skipped. * If matching by family is either successful or bypassed, a rule and a socket * are matched by ip protocol. * If 'protocol' is 0, matching is bypassed. @@ -49,3 +53,4 @@ }; #define SOCKET_BIND_MAX_RULES 128 +#define SOCKET_BIND_RULE_AF_MATCH_NOTHING UINT32_MAX diff -Nru systemd-252.23/src/core/bpf/socket_bind/socket-bind.bpf.c systemd-252.24/src/core/bpf/socket_bind/socket-bind.bpf.c --- systemd-252.23/src/core/bpf/socket_bind/socket-bind.bpf.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/core/bpf/socket_bind/socket-bind.bpf.c 2024-04-26 00:30:13.000000000 +0000 @@ -55,6 +55,9 @@ __u32 protocol, __u16 port, const struct socket_bind_rule *r) { + if (r->address_family == SOCKET_BIND_RULE_AF_MATCH_NOTHING) + return false; + return match_af(address_family, r) && match_protocol(protocol, r) && match_user_port(port, r); diff -Nru systemd-252.23/src/core/bpf-socket-bind.c systemd-252.24/src/core/bpf-socket-bind.c --- systemd-252.23/src/core/bpf-socket-bind.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/core/bpf-socket-bind.c 2024-04-26 00:30:13.000000000 +0000 @@ -32,6 +32,15 @@ assert(map_fd >= 0); + if (!head) { + static const struct socket_bind_rule val = { + .address_family = SOCKET_BIND_RULE_AF_MATCH_NOTHING, + }; + + if (sym_bpf_map_update_elem(map_fd, &i, &val, BPF_ANY) != 0) + return -errno; + } + LIST_FOREACH(socket_bind_items, item, head) { struct socket_bind_rule val = { .address_family = (uint32_t) item->address_family, diff -Nru systemd-252.23/src/core/dynamic-user.c systemd-252.24/src/core/dynamic-user.c --- systemd-252.23/src/core/dynamic-user.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/core/dynamic-user.c 2024-04-26 00:30:13.000000000 +0000 @@ -332,8 +332,10 @@ * the lock on the socket taken. */ k = receive_one_fd_iov(d->storage_socket[0], &iov, 1, MSG_DONTWAIT, &lock_fd); - if (k < 0) + if (k < 0) { + assert(errno_is_valid(-k)); return (int) k; + } *ret_uid = uid; *ret_lock_fd = lock_fd; diff -Nru systemd-252.23/src/core/main.c systemd-252.24/src/core/main.c --- systemd-252.23/src/core/main.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/core/main.c 2024-04-26 00:30:13.000000000 +0000 @@ -608,7 +608,7 @@ { "Manager", "CPUAffinity", config_parse_cpu_affinity2, 0, &arg_cpu_affinity }, { "Manager", "NUMAPolicy", config_parse_numa_policy, 0, &arg_numa_policy.type }, { "Manager", "NUMAMask", config_parse_numa_mask, 0, &arg_numa_policy }, - { "Manager", "JoinControllers", config_parse_warn_compat, DISABLED_CONFIGURATION, NULL }, + { "Manager", "JoinControllers", config_parse_warn_compat, DISABLED_LEGACY, NULL }, { "Manager", "RuntimeWatchdogSec", config_parse_watchdog_sec, 0, &arg_runtime_watchdog }, { "Manager", "RuntimeWatchdogPreSec", config_parse_watchdog_sec, 0, &arg_pretimeout_watchdog }, { "Manager", "RebootWatchdogSec", config_parse_watchdog_sec, 0, &arg_reboot_watchdog }, diff -Nru systemd-252.23/src/core/mount.c systemd-252.24/src/core/mount.c --- systemd-252.23/src/core/mount.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/core/mount.c 2024-04-26 00:30:13.000000000 +0000 @@ -1468,7 +1468,8 @@ if (IN_SET(m->state, MOUNT_REMOUNTING, MOUNT_REMOUNTING_SIGKILL, MOUNT_REMOUNTING_SIGTERM)) mount_set_reload_result(m, f); - else if (m->result == MOUNT_SUCCESS) + else if (m->result == MOUNT_SUCCESS && !IN_SET(m->state, MOUNT_MOUNTING, MOUNT_UNMOUNTING)) + /* MOUNT_MOUNTING and MOUNT_UNMOUNTING states need to be patched, see below. */ m->result = f; if (m->control_command) { @@ -1491,11 +1492,11 @@ switch (m->state) { case MOUNT_MOUNTING: - /* Our mount point has not appeared in mountinfo. Something went wrong. */ + /* Our mount point has not appeared in mountinfo. Something went wrong. */ if (f == MOUNT_SUCCESS) { - /* Either /bin/mount has an unexpected definition of success, - * or someone raced us and we lost. */ + /* Either /bin/mount has an unexpected definition of success, or someone raced us + * and we lost. */ log_unit_warning(UNIT(m), "Mount process finished, but there is no mount."); f = MOUNT_FAILURE_PROTOCOL; } @@ -1513,9 +1514,7 @@ break; case MOUNT_UNMOUNTING: - if (f == MOUNT_SUCCESS && m->from_proc_self_mountinfo) { - /* Still a mount point? If so, let's try again. Most likely there were multiple mount points * stacked on top of each other. We might exceed the timeout specified by the user overall, * but we will stop as soon as any one umount times out. */ @@ -1526,15 +1525,20 @@ mount_enter_unmounting(m); } else { log_unit_warning(u, "Mount still present after %u attempts to unmount, giving up.", m->n_retry_umount); - mount_enter_mounted(m, f); + mount_enter_mounted(m, MOUNT_FAILURE_PROTOCOL); } + } else if (f == MOUNT_FAILURE_EXIT_CODE && !m->from_proc_self_mountinfo) { + /* Hmm, umount process spawned by us failed, but the mount disappeared anyway? + * Maybe someone else is trying to unmount at the same time. */ + log_unit_notice(u, "Mount disappeared even though umount process failed, continuing."); + mount_enter_dead(m, MOUNT_SUCCESS); } else mount_enter_dead_or_mounted(m, f); break; - case MOUNT_UNMOUNTING_SIGKILL: case MOUNT_UNMOUNTING_SIGTERM: + case MOUNT_UNMOUNTING_SIGKILL: mount_enter_dead_or_mounted(m, f); break; @@ -2078,7 +2082,7 @@ * then remove it because of an internal error. E.g., fuse.sshfs seems * to do that when the connection fails. See #17617. To handle such the * case, let's once set the state back to mounting. Then, the unit can - * correctly enter the failed state later in mount_sigchld(). */ + * correctly enter the failed state later in mount_sigchld_event(). */ mount_set_state(mount, MOUNT_MOUNTING); break; diff -Nru systemd-252.23/src/core/service.c systemd-252.24/src/core/service.c --- systemd-252.23/src/core/service.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/core/service.c 2024-04-26 00:30:13.000000000 +0000 @@ -3378,8 +3378,10 @@ break; } - if (s->exit_type == SERVICE_EXIT_CGROUP && main_pid_good(s) <= 0) - service_enter_start_post(s); + if (s->exit_type == SERVICE_EXIT_CGROUP && main_pid_good(s) <= 0) { + service_enter_stop_post(s, SERVICE_SUCCESS); + break; + } _fallthrough_; case SERVICE_START_POST: @@ -3648,11 +3650,13 @@ default: assert_not_reached(); } - } else if (s->exit_type == SERVICE_EXIT_CGROUP && s->state == SERVICE_START) + } else if (s->exit_type == SERVICE_EXIT_CGROUP && s->state == SERVICE_START && + !IN_SET(s->type, SERVICE_NOTIFY, SERVICE_DBUS)) /* If a main process exits very quickly, this function might be executed * before service_dispatch_exec_io(). Since this function disabled IO events * to monitor the main process above, we need to update the state here too. - * Let's consider the process is successfully launched and exited. */ + * Let's consider the process is successfully launched and exited, but + * only when we're not expecting a readiness notification or dbus name. */ service_enter_start_post(s); } diff -Nru systemd-252.23/src/journal/cat.c systemd-252.24/src/journal/cat.c --- systemd-252.23/src/journal/cat.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/journal/cat.c 2024-04-26 00:30:13.000000000 +0000 @@ -10,6 +10,7 @@ #include "sd-journal.h" #include "alloc-util.h" +#include "env-util.h" #include "fd-util.h" #include "main-func.h" #include "parse-argument.h" diff -Nru systemd-252.23/src/journal/journalctl.c systemd-252.24/src/journal/journalctl.c --- systemd-252.23/src/journal/journalctl.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/journal/journalctl.c 2024-04-26 00:30:13.000000000 +0000 @@ -336,7 +336,7 @@ " -u --unit=UNIT Show logs from the specified unit\n" " --user-unit=UNIT Show logs from the specified user unit\n" " -t --identifier=STRING Show entries with the specified syslog identifier\n" - " -p --priority=RANGE Show entries with the specified priority\n" + " -p --priority=RANGE Show entries within the specified priority range\n" " --facility=FACILITY... Show entries with the specified facilities\n" " -g --grep=PATTERN Show entries with MESSAGE matching PATTERN\n" " --case-sensitive[=BOOL] Force case sensitive or insensitive matching\n" diff -Nru systemd-252.23/src/journal-remote/journal-gatewayd.c systemd-252.24/src/journal-remote/journal-gatewayd.c --- systemd-252.23/src/journal-remote/journal-gatewayd.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/journal-remote/journal-gatewayd.c 2024-04-26 00:30:13.000000000 +0000 @@ -45,6 +45,7 @@ STATIC_DESTRUCTOR_REGISTER(arg_key_pem, erase_and_freep); STATIC_DESTRUCTOR_REGISTER(arg_cert_pem, freep); STATIC_DESTRUCTOR_REGISTER(arg_trust_pem, freep); +STATIC_DESTRUCTOR_REGISTER(arg_file, strv_freep); typedef struct RequestMeta { sd_journal *journal; diff -Nru systemd-252.23/src/journal-remote/journal-remote-main.c systemd-252.24/src/journal-remote/journal-remote-main.c --- systemd-252.23/src/journal-remote/journal-remote-main.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/journal-remote/journal-remote-main.c 2024-04-26 00:30:13.000000000 +0000 @@ -560,24 +560,6 @@ ********************************************************************** **********************************************************************/ -static int setup_signals(RemoteServer *s) { - int r; - - assert(s); - - assert_se(sigprocmask_many(SIG_SETMASK, NULL, SIGINT, SIGTERM, -1) >= 0); - - r = sd_event_add_signal(s->events, &s->sigterm_event, SIGTERM, NULL, s); - if (r < 0) - return r; - - r = sd_event_add_signal(s->events, &s->sigint_event, SIGINT, NULL, s); - if (r < 0) - return r; - - return 0; -} - static int setup_raw_socket(RemoteServer *s, const char *address) { int fd; @@ -605,9 +587,9 @@ if (r < 0) return r; - r = setup_signals(s); + r = sd_event_set_signal_exit(s->events, true); if (r < 0) - return log_error_errno(r, "Failed to set up signals: %m"); + return log_error_errno(r, "Failed to install SIGINT/SIGTERM handlers: %m"); n = sd_listen_fds(true); if (n < 0) diff -Nru systemd-252.23/src/journal-remote/journal-remote.c systemd-252.24/src/journal-remote/journal-remote.c --- systemd-252.23/src/journal-remote/journal-remote.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/journal-remote/journal-remote.c 2024-04-26 00:30:13.000000000 +0000 @@ -362,8 +362,6 @@ writer_unref(s->_single_writer); hashmap_free(s->writers); - sd_event_source_unref(s->sigterm_event); - sd_event_source_unref(s->sigint_event); sd_event_source_unref(s->listen_event); sd_event_unref(s->events); @@ -497,7 +495,9 @@ switch (socket_address_family(addr)) { case AF_INET: - case AF_INET6: { + case AF_INET6: + case AF_VSOCK: + case AF_UNIX: { _cleanup_free_ char *a = NULL; char *b; diff -Nru systemd-252.23/src/journal-remote/journal-remote.h systemd-252.24/src/journal-remote/journal-remote.h --- systemd-252.23/src/journal-remote/journal-remote.h 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/journal-remote/journal-remote.h 2024-04-26 00:30:13.000000000 +0000 @@ -26,7 +26,7 @@ size_t active; sd_event *events; - sd_event_source *sigterm_event, *sigint_event, *listen_event; + sd_event_source *listen_event; Hashmap *writers; Writer *_single_writer; diff -Nru systemd-252.23/src/journal-remote/journal-upload.c systemd-252.24/src/journal-remote/journal-upload.c --- systemd-252.23/src/journal-remote/journal-upload.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/journal-remote/journal-upload.c 2024-04-26 00:30:13.000000000 +0000 @@ -55,6 +55,8 @@ static const char *arg_save_state = NULL; static usec_t arg_network_timeout_usec = USEC_INFINITY; +STATIC_DESTRUCTOR_REGISTER(arg_file, strv_freep); + static void close_fd_input(Uploader *u); #define SERVER_ANSWER_KEEP 2048 @@ -377,38 +379,6 @@ return r; } -static int dispatch_sigterm(sd_event_source *event, - const struct signalfd_siginfo *si, - void *userdata) { - Uploader *u = ASSERT_PTR(userdata); - - log_received_signal(LOG_INFO, si); - - close_fd_input(u); - close_journal_input(u); - - sd_event_exit(u->events, 0); - return 0; -} - -static int setup_signals(Uploader *u) { - int r; - - assert(u); - - assert_se(sigprocmask_many(SIG_SETMASK, NULL, SIGINT, SIGTERM, -1) >= 0); - - r = sd_event_add_signal(u->events, &u->sigterm_event, SIGTERM, dispatch_sigterm, u); - if (r < 0) - return r; - - r = sd_event_add_signal(u->events, &u->sigint_event, SIGINT, dispatch_sigterm, u); - if (r < 0) - return r; - - return 0; -} - static int setup_uploader(Uploader *u, const char *url, const char *state_file) { int r; const char *host, *proto = ""; @@ -448,9 +418,9 @@ if (r < 0) return log_error_errno(r, "sd_event_default failed: %m"); - r = setup_signals(u); + r = sd_event_set_signal_exit(u->events, true); if (r < 0) - return log_error_errno(r, "Failed to set up signals: %m"); + return log_error_errno(r, "Failed to install SIGINT/SIGTERM handlers: %m"); (void) sd_watchdog_enabled(false, &u->watchdog_usec); @@ -474,8 +444,6 @@ close_fd_input(u); close_journal_input(u); - sd_event_source_unref(u->sigterm_event); - sd_event_source_unref(u->sigint_event); sd_event_unref(u->events); } diff -Nru systemd-252.23/src/journal-remote/journal-upload.h systemd-252.24/src/journal-remote/journal-upload.h --- systemd-252.23/src/journal-remote/journal-upload.h 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/journal-remote/journal-upload.h 2024-04-26 00:30:13.000000000 +0000 @@ -25,7 +25,6 @@ typedef struct Uploader { sd_event *events; - sd_event_source *sigint_event, *sigterm_event; char *url; CURL *easy; diff -Nru systemd-252.23/src/libsystemd/sd-bus/bus-error.c systemd-252.24/src/libsystemd/sd-bus/bus-error.c --- systemd-252.23/src/libsystemd/sd-bus/bus-error.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/libsystemd/sd-bus/bus-error.c 2024-04-26 00:30:13.000000000 +0000 @@ -278,14 +278,16 @@ va_start(ap, format); r = sd_bus_error_setfv(e, name, format, ap); - assert(!name || r < 0); + if (name) + assert(r < 0); va_end(ap); return r; } r = sd_bus_error_set(e, name, NULL); - assert(!name || r < 0); + if (name) + assert(r < 0); return r; } diff -Nru systemd-252.23/src/libsystemd/sd-device/device-private.h systemd-252.24/src/libsystemd/sd-device/device-private.h --- systemd-252.23/src/libsystemd/sd-device/device-private.h 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/libsystemd/sd-device/device-private.h 2024-04-26 00:30:13.000000000 +0000 @@ -19,7 +19,10 @@ int device_get_property_bool(sd_device *device, const char *key); int device_get_sysattr_int(sd_device *device, const char *sysattr, int *ret_value); -int device_get_sysattr_unsigned(sd_device *device, const char *sysattr, unsigned *ret_value); +int device_get_sysattr_unsigned_full(sd_device *device, const char *sysattr, unsigned base, unsigned *ret_value); +static inline int device_get_sysattr_unsigned(sd_device *device, const char *sysattr, unsigned *ret_value) { + return device_get_sysattr_unsigned_full(device, sysattr, 0, ret_value); +} int device_get_sysattr_bool(sd_device *device, const char *sysattr); int device_get_device_id(sd_device *device, const char **ret); int device_get_devlink_priority(sd_device *device, int *ret); diff -Nru systemd-252.23/src/libsystemd/sd-device/sd-device.c systemd-252.24/src/libsystemd/sd-device/sd-device.c --- systemd-252.23/src/libsystemd/sd-device/sd-device.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/libsystemd/sd-device/sd-device.c 2024-04-26 00:30:13.000000000 +0000 @@ -2368,7 +2368,7 @@ return v > 0; } -int device_get_sysattr_unsigned(sd_device *device, const char *sysattr, unsigned *ret_value) { +int device_get_sysattr_unsigned_full(sd_device *device, const char *sysattr, unsigned base, unsigned *ret_value) { const char *value; int r; @@ -2377,7 +2377,7 @@ return r; unsigned v; - r = safe_atou(value, &v); + r = safe_atou_full(value, base, &v); if (r < 0) return log_device_debug_errno(device, r, "Failed to parse '%s' attribute: %m", sysattr); diff -Nru systemd-252.23/src/libsystemd/sd-event/sd-event.c systemd-252.24/src/libsystemd/sd-event/sd-event.c --- systemd-252.23/src/libsystemd/sd-event/sd-event.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/libsystemd/sd-event/sd-event.c 2024-04-26 00:30:13.000000000 +0000 @@ -2034,7 +2034,7 @@ wd = inotify_add_watch_fd(d->inotify_data->fd, d->fd, combined_mask); if (wd < 0) - return -errno; + return wd; if (d->wd < 0) { r = hashmap_put(d->inotify_data->wd, INT_TO_PTR(wd), d); @@ -2255,7 +2255,7 @@ } _public_ int sd_event_source_set_io_fd(sd_event_source *s, int fd) { - int r; + int saved_fd, r; assert_return(s, -EINVAL); assert_return(fd >= 0, -EBADF); @@ -2265,16 +2265,12 @@ if (s->io.fd == fd) return 0; - if (event_source_is_offline(s)) { - s->io.fd = fd; - s->io.registered = false; - } else { - int saved_fd; + saved_fd = s->io.fd; + s->io.fd = fd; - saved_fd = s->io.fd; - assert(s->io.registered); + assert(event_source_is_offline(s) == !s->io.registered); - s->io.fd = fd; + if (s->io.registered) { s->io.registered = false; r = source_io_register(s, s->enabled, s->io.events); @@ -2287,6 +2283,9 @@ (void) epoll_ctl(s->event->epoll_fd, EPOLL_CTL_DEL, saved_fd, NULL); } + if (s->io.owned) + safe_close(saved_fd); + return 0; } diff -Nru systemd-252.23/src/libsystemd/sd-event/test-event.c systemd-252.24/src/libsystemd/sd-event/test-event.c --- systemd-252.23/src/libsystemd/sd-event/test-event.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/libsystemd/sd-event/test-event.c 2024-04-26 00:30:13.000000000 +0000 @@ -809,4 +809,22 @@ assert_se(sd_event_wait(e, 0) == 0); } +TEST(sd_event_source_set_io_fd) { + _cleanup_(sd_event_source_unrefp) sd_event_source *s = NULL; + _cleanup_(sd_event_unrefp) sd_event *e = NULL; + _cleanup_close_pair_ int pfd_a[2] = { -EBADF, -EBADF }, pfd_b[2] = { -EBADF, -EBADF }; + + assert_se(sd_event_default(&e) >= 0); + + assert_se(pipe2(pfd_a, O_CLOEXEC) >= 0); + assert_se(pipe2(pfd_b, O_CLOEXEC) >= 0); + + assert_se(sd_event_add_io(e, &s, pfd_a[0], EPOLLIN, NULL, INT_TO_PTR(-ENOANO)) >= 0); + assert_se(sd_event_source_set_io_fd_own(s, true) >= 0); + TAKE_FD(pfd_a[0]); + + assert_se(sd_event_source_set_io_fd(s, pfd_b[0]) >= 0); + TAKE_FD(pfd_b[0]); +} + DEFINE_TEST_MAIN(LOG_DEBUG); diff -Nru systemd-252.23/src/libsystemd/sd-journal/journal-verify.c systemd-252.24/src/libsystemd/sd-journal/journal-verify.c --- systemd-252.23/src/libsystemd/sd-journal/journal-verify.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/libsystemd/sd-journal/journal-verify.c 2024-04-26 00:30:13.000000000 +0000 @@ -163,7 +163,7 @@ int r; if (le64toh(o->data.entry_offset) == 0) - warning(offset, "Unused data (entry_offset==0)"); + debug(offset, "Unused data (entry_offset==0)"); if ((le64toh(o->data.entry_offset) == 0) ^ (le64toh(o->data.n_entries) == 0)) { error(offset, "Bad n_entries: %"PRIu64, le64toh(o->data.n_entries)); diff -Nru systemd-252.23/src/libsystemd/sd-journal/sd-journal.c systemd-252.24/src/libsystemd/sd-journal/sd-journal.c --- systemd-252.23/src/libsystemd/sd-journal/sd-journal.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/libsystemd/sd-journal/sd-journal.c 2024-04-26 00:30:13.000000000 +0000 @@ -1593,7 +1593,7 @@ m->wd = inotify_add_watch_fd(j->inotify_fd, fd, mask); if (m->wd < 0) { - log_debug_errno(errno, "Failed to watch journal directory '%s', ignoring: %m", m->path); + log_debug_errno(m->wd, "Failed to watch journal directory '%s', ignoring: %m", m->path); return; } diff -Nru systemd-252.23/src/resolve/resolved-bus.c systemd-252.24/src/resolve/resolved-bus.c --- systemd-252.23/src/resolve/resolved-bus.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/resolve/resolved-bus.c 2024-04-26 00:30:13.000000000 +0000 @@ -12,6 +12,7 @@ #include "missing_capability.h" #include "resolved-bus.h" #include "resolved-def.h" +#include "resolved-dns-stream.h" #include "resolved-dns-synthesize.h" #include "resolved-dnssd-bus.h" #include "resolved-dnssd.h" @@ -1854,6 +1855,7 @@ bus_client_log(message, "server feature reset"); + (void) dns_stream_disconnect_all(m); manager_reset_server_features(m); return sd_bus_reply_method_return(message, NULL); @@ -2240,9 +2242,15 @@ if (b) return 0; - log_debug("Coming back from suspend, verifying all RRs..."); + log_debug("Coming back from suspend, closing all TCP connections..."); + (void) dns_stream_disconnect_all(m); + + log_debug("Coming back from suspend, resetting all probed server features..."); + manager_reset_server_features(m); + log_debug("Coming back from suspend, verifying all RRs..."); manager_verify_all(m); + return 0; } diff -Nru systemd-252.23/src/resolve/resolved-dns-answer.c systemd-252.24/src/resolve/resolved-dns-answer.c --- systemd-252.23/src/resolve/resolved-dns-answer.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/resolve/resolved-dns-answer.c 2024-04-26 00:30:13.000000000 +0000 @@ -181,11 +181,23 @@ exist = ordered_set_get(a->items, &tmp); if (exist) { - /* There's already an RR of the same RRset in place! Let's see if the TTLs more or less - * match. We don't really care if they match precisely, but we do care whether one is 0 and - * the other is not. See RFC 2181, Section 5.2. */ - if ((rr->ttl == 0) != (exist->rr->ttl == 0)) - return -EINVAL; + /* There's already an RR of the same RRset in place! Let's see if the TTLs more or + * less match. RFC 2181, Section 5.2 suggests clients should reject RRsets + * containing RRs with differing TTLs. We are more tolerant of this situation except + * if one RR has a zero TTL and the other a nonzero TTL. In mDNS, zero TTLs are + * special, so we must error in that case. */ + if ((rr->ttl == 0) != (exist->rr->ttl == 0)) { + if ((exist->flags | flags) & DNS_ANSWER_REFUSE_TTL_NO_MATCH) + return log_debug_errno( + SYNTHETIC_ERRNO(EINVAL), + "Refusing to merge RRs with zero TTL and non-zero TTL: %s vs. %s", + dns_resource_record_to_string(rr), + dns_resource_record_to_string(exist->rr)); + + log_debug("Merging RRs with zero TTL and non-zero TTL (not RFC 2181/5.2 compliant): %s vs. %s", + dns_resource_record_to_string(rr), + dns_resource_record_to_string(exist->rr)); + } /* Entry already exists, keep the entry with the higher TTL. */ if (rr->ttl > exist->rr->ttl) { diff -Nru systemd-252.23/src/resolve/resolved-dns-answer.h systemd-252.24/src/resolve/resolved-dns-answer.h --- systemd-252.23/src/resolve/resolved-dns-answer.h 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/resolve/resolved-dns-answer.h 2024-04-26 00:30:13.000000000 +0000 @@ -14,14 +14,15 @@ * Note that we usually encode the empty DnsAnswer object as a simple NULL. */ typedef enum DnsAnswerFlags { - DNS_ANSWER_AUTHENTICATED = 1 << 0, /* Item has been authenticated */ - DNS_ANSWER_CACHEABLE = 1 << 1, /* Item is subject to caching */ - DNS_ANSWER_SHARED_OWNER = 1 << 2, /* For mDNS: RRset may be owner by multiple peers */ - DNS_ANSWER_CACHE_FLUSH = 1 << 3, /* For mDNS: sets cache-flush bit in the rrclass of response records */ - DNS_ANSWER_GOODBYE = 1 << 4, /* For mDNS: item is subject to disappear */ - DNS_ANSWER_SECTION_ANSWER = 1 << 5, /* When parsing: RR originates from answer section */ - DNS_ANSWER_SECTION_AUTHORITY = 1 << 6, /* When parsing: RR originates from authority section */ - DNS_ANSWER_SECTION_ADDITIONAL = 1 << 7, /* When parsing: RR originates from additional section */ + DNS_ANSWER_AUTHENTICATED = 1 << 0, /* Item has been authenticated */ + DNS_ANSWER_CACHEABLE = 1 << 1, /* Item is subject to caching */ + DNS_ANSWER_SHARED_OWNER = 1 << 2, /* For mDNS: RRset may be owner by multiple peers */ + DNS_ANSWER_CACHE_FLUSH = 1 << 3, /* For mDNS: sets cache-flush bit in the rrclass of response records */ + DNS_ANSWER_GOODBYE = 1 << 4, /* For mDNS: item is subject to disappear */ + DNS_ANSWER_SECTION_ANSWER = 1 << 5, /* When parsing: RR originates from answer section */ + DNS_ANSWER_SECTION_AUTHORITY = 1 << 6, /* When parsing: RR originates from authority section */ + DNS_ANSWER_SECTION_ADDITIONAL = 1 << 7, /* When parsing: RR originates from additional section */ + DNS_ANSWER_REFUSE_TTL_NO_MATCH = 1 << 8, /* For mDNS; refuse to merge a zero TTL RR with a nonzero TTL RR */ DNS_ANSWER_MASK_SECTIONS = DNS_ANSWER_SECTION_ANSWER| DNS_ANSWER_SECTION_AUTHORITY| diff -Nru systemd-252.23/src/resolve/resolved-dns-packet.c systemd-252.24/src/resolve/resolved-dns-packet.c --- systemd-252.23/src/resolve/resolved-dns-packet.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/resolve/resolved-dns-packet.c 2024-04-26 00:30:13.000000000 +0000 @@ -2365,8 +2365,11 @@ } else { DnsAnswerFlags flags = 0; - if (p->protocol == DNS_PROTOCOL_MDNS && !cache_flush) - flags |= DNS_ANSWER_SHARED_OWNER; + if (p->protocol == DNS_PROTOCOL_MDNS) { + flags |= DNS_ANSWER_REFUSE_TTL_NO_MATCH; + if (!cache_flush) + flags |= DNS_ANSWER_SHARED_OWNER; + } /* According to RFC 4795, section 2.9. only the RRs from the Answer section shall be * cached. Hence mark only those RRs as cacheable by default, but not the ones from diff -Nru systemd-252.23/src/resolve/resolved-dns-query.c systemd-252.24/src/resolve/resolved-dns-query.c --- systemd-252.23/src/resolve/resolved-dns-query.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/resolve/resolved-dns-query.c 2024-04-26 00:30:13.000000000 +0000 @@ -57,6 +57,21 @@ } } +static void dns_query_candidate_abandon(DnsQueryCandidate *c) { + DnsTransaction *t; + + assert(c); + + /* Abandon all the DnsTransactions attached to this query */ + + while ((t = set_steal_first(c->transactions))) { + t->wait_for_answer = true; + set_remove(t->notify_query_candidates, c); + set_remove(t->notify_query_candidates_done, c); + dns_transaction_gc(t); + } +} + static DnsQueryCandidate* dns_query_candidate_unlink(DnsQueryCandidate *c) { assert(c); @@ -354,6 +369,16 @@ dns_query_candidate_stop(c); } +static void dns_query_abandon(DnsQuery *q) { + assert(q); + + /* Thankfully transactions have their own timeouts */ + event_source_disable(q->timeout_event_source); + + LIST_FOREACH(candidates_by_query, c, q->candidates) + dns_query_candidate_abandon(c); +} + static void dns_query_unlink_candidates(DnsQuery *q) { assert(q); @@ -588,7 +613,7 @@ (void) manager_monitor_send(q->manager, q->state, q->answer_rcode, q->answer_errno, q->question_idna, q->question_utf8, q->question_bypass, q->collected_questions, q->answer); - dns_query_stop(q); + dns_query_abandon(q); if (q->complete) q->complete(q); } diff -Nru systemd-252.23/src/resolve/resolved-dns-rr.c systemd-252.24/src/resolve/resolved-dns-rr.c --- systemd-252.23/src/resolve/resolved-dns-rr.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/resolve/resolved-dns-rr.c 2024-04-26 00:30:13.000000000 +0000 @@ -181,6 +181,23 @@ dns_name_endswith(dns_resource_key_name(key), "_udp.local"); } +bool dns_resource_key_is_dnssd_two_label_ptr(const DnsResourceKey *key) { + assert(key); + + /* Check if this is a PTR resource key used in Service Instance + * Enumeration as described in RFC6763 § 4.1, excluding selective + * service names described in RFC6763 § 7.1. */ + + if (key->type != DNS_TYPE_PTR) + return false; + + const char *name = dns_resource_key_name(key); + if (dns_name_parent(&name) <= 0) + return false; + + return dns_name_equal(name, "_tcp.local") || dns_name_equal(name, "_udp.local"); +} + int dns_resource_key_equal(const DnsResourceKey *a, const DnsResourceKey *b) { int r; diff -Nru systemd-252.23/src/resolve/resolved-dns-rr.h systemd-252.24/src/resolve/resolved-dns-rr.h --- systemd-252.23/src/resolve/resolved-dns-rr.h 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/resolve/resolved-dns-rr.h 2024-04-26 00:30:13.000000000 +0000 @@ -305,6 +305,7 @@ const char* dns_resource_key_name(const DnsResourceKey *key); bool dns_resource_key_is_address(const DnsResourceKey *key); bool dns_resource_key_is_dnssd_ptr(const DnsResourceKey *key); +bool dns_resource_key_is_dnssd_two_label_ptr(const DnsResourceKey *key); int dns_resource_key_equal(const DnsResourceKey *a, const DnsResourceKey *b); int dns_resource_key_match_rr(const DnsResourceKey *key, DnsResourceRecord *rr, const char *search_domain); int dns_resource_key_match_cname_or_dname(const DnsResourceKey *key, const DnsResourceKey *cname, const char *search_domain); diff -Nru systemd-252.23/src/resolve/resolved-dns-scope.c systemd-252.24/src/resolve/resolved-dns-scope.c --- systemd-252.23/src/resolve/resolved-dns-scope.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/resolve/resolved-dns-scope.c 2024-04-26 00:30:13.000000000 +0000 @@ -424,7 +424,15 @@ return r; } - if (ifindex != 0) { + bool addr_is_nonlocal = s->link && + !manager_find_link_address(s->manager, sa.sa.sa_family, sockaddr_in_addr(&sa.sa)) && + in_addr_is_localhost(sa.sa.sa_family, sockaddr_in_addr(&sa.sa)) == 0; + + if (addr_is_nonlocal && ifindex != 0) { + /* As a special exception we don't use UNICAST_IF if we notice that the specified IP address + * is on the local host. Otherwise, destination addresses on the local host result in + * EHOSTUNREACH, since Linux won't send the packets out of the specified interface, but + * delivers them directly to the local socket. */ r = socket_set_unicast_if(fd, sa.sa.sa_family, ifindex); if (r < 0) return r; @@ -463,19 +471,13 @@ else { bool bound = false; - /* Let's temporarily bind the socket to the specified ifindex. The kernel currently takes - * only the SO_BINDTODEVICE/SO_BINDTOINDEX ifindex into account when making routing decisions + /* Let's temporarily bind the socket to the specified ifindex. Older kernels only take + * the SO_BINDTODEVICE/SO_BINDTOINDEX ifindex into account when making routing decisions * in connect() — and not IP_UNICAST_IF. We don't really want any of the other semantics of * SO_BINDTODEVICE/SO_BINDTOINDEX, hence we immediately unbind the socket after the fact * again. - * - * As a special exception we don't do this if we notice that the specified IP address is on - * the local host. SO_BINDTODEVICE in combination with destination addresses on the local - * host result in EHOSTUNREACH, since Linux won't send the packets out of the specified - * interface, but delivers them directly to the local socket. */ - if (s->link && - !manager_find_link_address(s->manager, sa.sa.sa_family, sockaddr_in_addr(&sa.sa)) && - in_addr_is_localhost(sa.sa.sa_family, sockaddr_in_addr(&sa.sa)) == 0) { + */ + if (addr_is_nonlocal) { r = socket_bind_to_ifindex(fd, ifindex); if (r < 0) return r; @@ -594,6 +596,7 @@ /* This returns the following return values: * * DNS_SCOPE_NO → This scope is not suitable for lookups of this domain, at all + * DNS_SCOPE_LAST_RESORT→ This scope is not suitable, unless we have no alternative * DNS_SCOPE_MAYBE → This scope is suitable, but only if nothing else wants it * DNS_SCOPE_YES_BASE+n → This scope is suitable, and 'n' suffix labels match * @@ -739,7 +742,7 @@ if ((s->family == AF_INET && dns_name_endswith(domain, "in-addr.arpa") > 0) || (s->family == AF_INET6 && dns_name_endswith(domain, "ip6.arpa") > 0)) - return DNS_SCOPE_MAYBE; + return DNS_SCOPE_LAST_RESORT; if ((dns_name_endswith(domain, "local") > 0 && /* only resolve names ending in .local via mDNS */ dns_name_equal(domain, "local") == 0 && /* but not the single-label "local" name itself */ @@ -762,7 +765,7 @@ if ((s->family == AF_INET && dns_name_endswith(domain, "in-addr.arpa") > 0) || (s->family == AF_INET6 && dns_name_endswith(domain, "ip6.arpa") > 0)) - return DNS_SCOPE_MAYBE; + return DNS_SCOPE_LAST_RESORT; if ((dns_name_is_single_label(domain) && /* only resolve single label names via LLMNR */ !is_gateway_hostname(domain) && /* don't resolve "_gateway" with LLMNR, let local synthesizing logic handle that */ @@ -1441,9 +1444,10 @@ continue; } - /* Collect service types for _services._dns-sd._udp.local RRs in a set */ + /* Collect service types for _services._dns-sd._udp.local RRs in a set. Only two-label names + * (not selective names) are considered according to RFC6763 § 9. */ if (!scope->announced && - dns_resource_key_is_dnssd_ptr(z->rr->key)) { + dns_resource_key_is_dnssd_two_label_ptr(z->rr->key)) { if (!set_contains(types, dns_resource_key_name(z->rr->key))) { r = set_ensure_put(&types, &dns_name_hash_ops, dns_resource_key_name(z->rr->key)); if (r < 0) diff -Nru systemd-252.23/src/resolve/resolved-dns-scope.h systemd-252.24/src/resolve/resolved-dns-scope.h --- systemd-252.23/src/resolve/resolved-dns-scope.h 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/resolve/resolved-dns-scope.h 2024-04-26 00:30:13.000000000 +0000 @@ -18,6 +18,7 @@ typedef enum DnsScopeMatch { DNS_SCOPE_NO, + DNS_SCOPE_LAST_RESORT, DNS_SCOPE_MAYBE, DNS_SCOPE_YES_BASE, /* Add the number of matching labels to this */ DNS_SCOPE_YES_END = DNS_SCOPE_YES_BASE + DNS_N_LABELS_MAX, diff -Nru systemd-252.23/src/resolve/resolved-dns-stream.c systemd-252.24/src/resolve/resolved-dns-stream.c --- systemd-252.23/src/resolve/resolved-dns-stream.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/resolve/resolved-dns-stream.c 2024-04-26 00:30:13.000000000 +0000 @@ -593,3 +593,44 @@ dns_server_unref_stream(s->server); } + +DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR( + dns_stream_hash_ops, + void, + trivial_hash_func, + trivial_compare_func, + dns_stream_unref); + +int dns_stream_disconnect_all(Manager *m) { + _cleanup_(set_freep) Set *closed = NULL; + int r; + + assert(m); + + /* Terminates all TCP connections (called after system suspend for example, to speed up recovery) */ + + log_info("Closing all remaining TCP connections."); + + bool restart; + do { + restart = false; + + LIST_FOREACH(streams, s, m->dns_streams) { + r = set_ensure_put(&closed, &dns_stream_hash_ops, s); + if (r < 0) + return log_oom(); + if (r > 0) { + /* Haven't seen this one before. Close it. */ + dns_stream_ref(s); + (void) dns_stream_complete(s, ECONNRESET); + + /* This might have a ripple effect, let's hence no look at the list further, + * but scan from the beginning again */ + restart = true; + break; + } + } + } while (restart); + + return 0; +} diff -Nru systemd-252.23/src/resolve/resolved-dns-stream.h systemd-252.24/src/resolve/resolved-dns-stream.h --- systemd-252.23/src/resolve/resolved-dns-stream.h 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/resolve/resolved-dns-stream.h 2024-04-26 00:30:13.000000000 +0000 @@ -126,3 +126,4 @@ } void dns_stream_detach(DnsStream *s); +int dns_stream_disconnect_all(Manager *m); diff -Nru systemd-252.23/src/resolve/resolved-dns-stub.c systemd-252.24/src/resolve/resolved-dns-stub.c --- systemd-252.23/src/resolve/resolved-dns-stub.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/resolve/resolved-dns-stub.c 2024-04-26 00:30:13.000000000 +0000 @@ -837,12 +837,20 @@ break; case DNS_TRANSACTION_NO_SERVERS: + /* We're not configured to give answers for this question. Refuse it. */ + (void) dns_stub_send_reply(q, DNS_RCODE_REFUSED); + break; + + case DNS_TRANSACTION_RR_TYPE_UNSUPPORTED: + /* This RR Type is not implemented */ + (void) dns_stub_send_reply(q, DNS_RCODE_NOTIMP); + break; + case DNS_TRANSACTION_INVALID_REPLY: case DNS_TRANSACTION_ERRNO: case DNS_TRANSACTION_ABORTED: case DNS_TRANSACTION_DNSSEC_FAILED: case DNS_TRANSACTION_NO_TRUST_ANCHOR: - case DNS_TRANSACTION_RR_TYPE_UNSUPPORTED: case DNS_TRANSACTION_NETWORK_DOWN: case DNS_TRANSACTION_NO_SOURCE: case DNS_TRANSACTION_STUB_LOOP: diff -Nru systemd-252.23/src/resolve/resolved-dns-transaction.c systemd-252.24/src/resolve/resolved-dns-transaction.c --- systemd-252.23/src/resolve/resolved-dns-transaction.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/resolve/resolved-dns-transaction.c 2024-04-26 00:30:13.000000000 +0000 @@ -175,6 +175,9 @@ if (t->block_gc > 0) return t; + if (t->wait_for_answer && IN_SET(t->state, DNS_TRANSACTION_PENDING, DNS_TRANSACTION_VALIDATING)) + return t; + if (set_isempty(t->notify_query_candidates) && set_isempty(t->notify_query_candidates_done) && set_isempty(t->notify_zone_items) && @@ -2238,7 +2241,7 @@ return 1; } -static int dns_transaction_request_dnssec_rr(DnsTransaction *t, DnsResourceKey *key) { +static int dns_transaction_request_dnssec_rr_full(DnsTransaction *t, DnsResourceKey *key, DnsTransaction **ret) { _cleanup_(dns_answer_unrefp) DnsAnswer *a = NULL; DnsTransaction *aux; int r; @@ -2255,13 +2258,18 @@ if (r < 0) return r; + if (ret) + *ret = NULL; return 0; } /* This didn't work, ask for it via the network/cache then. */ r = dns_transaction_add_dnssec_transaction(t, key, &aux); - if (r == -ELOOP) /* This would result in a cyclic dependency */ + if (r == -ELOOP) { /* This would result in a cyclic dependency */ + if (ret) + *ret = NULL; return 0; + } if (r < 0) return r; @@ -2269,11 +2277,19 @@ r = dns_transaction_go(aux); if (r < 0) return r; + if (ret) + *ret = aux; } return 1; } +static int dns_transaction_request_dnssec_rr(DnsTransaction *t, DnsResourceKey *key) { + assert(t); + assert(key); + return dns_transaction_request_dnssec_rr_full(t, key, NULL); +} + static int dns_transaction_negative_trust_anchor_lookup(DnsTransaction *t, const char *name) { int r; @@ -2374,6 +2390,8 @@ int dns_transaction_request_dnssec_keys(DnsTransaction *t) { DnsResourceRecord *rr; + /* Have we already requested a record that would be sufficient to validate an insecure delegation? */ + bool chased_insecure = false; int r; assert(t); @@ -2386,11 +2404,11 @@ * - For RRSIG we get the matching DNSKEY * - For DNSKEY we get the matching DS * - For unsigned SOA/NS we get the matching DS - * - For unsigned CNAME/DNAME/DS we get the parent SOA RR - * - For other unsigned RRs we get the matching SOA RR + * - For unsigned CNAME/DNAME/DS we get the parent DS RR + * - For other unsigned RRs we get the matching DS RR * - For SOA/NS queries with no matching response RR, and no NSEC/NSEC3, the DS RR - * - For DS queries with no matching response RRs, and no NSEC/NSEC3, the parent's SOA RR - * - For other queries with no matching response RRs, and no NSEC/NSEC3, the SOA RR + * - For DS queries with no matching response RRs, and no NSEC/NSEC3, the parent's DS RR + * - For other queries with no matching response RRs, and no NSEC/NSEC3, the DS RR */ if (FLAGS_SET(t->query_flags, SD_RESOLVED_NO_VALIDATE) || t->scope->dnssec_mode == DNSSEC_NO) @@ -2417,6 +2435,7 @@ case DNS_TYPE_RRSIG: { /* For each RRSIG we request the matching DNSKEY */ _cleanup_(dns_resource_key_unrefp) DnsResourceKey *dnskey = NULL; + DnsTransaction *aux; /* If this RRSIG is about a DNSKEY RR and the * signer is the same as the owner, then we @@ -2453,9 +2472,22 @@ log_debug("Requesting DNSKEY to validate transaction %" PRIu16" (%s, RRSIG with key tag: %" PRIu16 ").", t->id, dns_resource_key_name(rr->key), rr->rrsig.key_tag); - r = dns_transaction_request_dnssec_rr(t, dnskey); + r = dns_transaction_request_dnssec_rr_full(t, dnskey, &aux); if (r < 0) return r; + + /* If we are requesting a DNSKEY, we can anticiapte that we will want the matching DS + * in the near future. Let's request it in advance so we don't have to wait in the + * common case. */ + if (aux) { + _cleanup_(dns_resource_key_unrefp) DnsResourceKey *ds = + dns_resource_key_new(rr->key->class, DNS_TYPE_DS, dns_resource_key_name(dnskey)); + if (!ds) + return -ENOMEM; + r = dns_transaction_request_dnssec_rr(t, ds); + if (r < 0) + return r; + } break; } @@ -2530,6 +2562,7 @@ if (r > 0) continue; + chased_insecure = true; ds = dns_resource_key_new(rr->key->class, DNS_TYPE_DS, dns_resource_key_name(rr->key)); if (!ds) return -ENOMEM; @@ -2546,11 +2579,11 @@ case DNS_TYPE_DS: case DNS_TYPE_CNAME: case DNS_TYPE_DNAME: { - _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL; + _cleanup_(dns_resource_key_unrefp) DnsResourceKey *ds = NULL; const char *name; /* CNAMEs and DNAMEs cannot be located at a - * zone apex, hence ask for the parent SOA for + * zone apex, hence ask for the parent DS for * unsigned CNAME/DNAME RRs, maybe that's the * apex. But do all that only if this is * actually a response to our original @@ -2584,13 +2617,13 @@ if (r == 0) continue; - soa = dns_resource_key_new(rr->key->class, DNS_TYPE_SOA, name); - if (!soa) + ds = dns_resource_key_new(rr->key->class, DNS_TYPE_DS, name); + if (!ds) return -ENOMEM; - log_debug("Requesting parent SOA to validate transaction %" PRIu16 " (%s, unsigned CNAME/DNAME/DS RRset).", + log_debug("Requesting parent DS to validate transaction %" PRIu16 " (%s, unsigned CNAME/DNAME/DS RRset).", t->id, dns_resource_key_name(rr->key)); - r = dns_transaction_request_dnssec_rr(t, soa); + r = dns_transaction_request_dnssec_rr(t, ds); if (r < 0) return r; @@ -2598,11 +2631,11 @@ } default: { - _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL; + _cleanup_(dns_resource_key_unrefp) DnsResourceKey *ds = NULL; /* For other unsigned RRsets (including * NSEC/NSEC3!), look for proof the zone is - * unsigned, by requesting the SOA RR of the + * unsigned, by requesting the DS RR of the * zone. However, do so only if they are * directly relevant to our original * question. */ @@ -2619,13 +2652,13 @@ if (r > 0) continue; - soa = dns_resource_key_new(rr->key->class, DNS_TYPE_SOA, dns_resource_key_name(rr->key)); - if (!soa) + ds = dns_resource_key_new(rr->key->class, DNS_TYPE_DS, dns_resource_key_name(rr->key)); + if (!ds) return -ENOMEM; - log_debug("Requesting SOA to validate transaction %" PRIu16 " (%s, unsigned non-SOA/NS RRset <%s>).", + log_debug("Requesting DS to validate transaction %" PRIu16 " (%s, unsigned non-SOA/NS RRset <%s>).", t->id, dns_resource_key_name(rr->key), dns_resource_record_to_string(rr)); - r = dns_transaction_request_dnssec_rr(t, soa); + r = dns_transaction_request_dnssec_rr(t, ds); if (r < 0) return r; break; @@ -2640,49 +2673,38 @@ if (r < 0) return r; if (r > 0) { - const char *name, *signed_status; - uint16_t type = 0; - - name = dns_resource_key_name(dns_transaction_key(t)); - signed_status = dns_answer_contains_nsec_or_nsec3(t->answer) ? "signed" : "unsigned"; - - /* If this was a SOA or NS request, then check if there's a DS RR for the same domain. Note that this - * could also be used as indication that we are not at a zone apex, but in real world setups there are - * too many broken DNS servers (Hello, incapdns.net!) where non-terminal zones return NXDOMAIN even - * though they have further children. If this was a DS request, then it's signed when the parent zone - * is signed, hence ask the parent SOA in that case. If this was any other RR then ask for the SOA RR, - * to see if that is signed. */ + const char *name = dns_resource_key_name(dns_transaction_key(t)); + bool was_signed = dns_answer_contains_nsec_or_nsec3(t->answer); - if (dns_transaction_key(t)->type == DNS_TYPE_DS) { - r = dns_name_parent(&name); - if (r > 0) { - type = DNS_TYPE_SOA; - log_debug("Requesting parent SOA (%s %s) to validate transaction %" PRIu16 " (%s, %s empty DS response).", - special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), name, t->id, - dns_resource_key_name(dns_transaction_key(t)), signed_status); - } else + /* If the response is empty, seek the DS for this name, just in case we're at a zone cut + * already, unless we just requested the DS, in which case we have to ask the parent to make + * progress. + * + * If this was an SOA or NS request, we could also skip to the parent, but in real world + * setups there are too many broken DNS servers (Hello, incapdns.net!) where non-terminal + * zones return NXDOMAIN even though they have further children. */ + + if (chased_insecure || was_signed) + /* In this case we already reqeusted what we need above. */ + name = NULL; + else if (dns_transaction_key(t)->type == DNS_TYPE_DS) + /* If the DS response is empty, we'll walk up the dns labels requesting DS until we + * find a referral to the SOA or hit it anyway and get a positive DS response. */ + if (dns_name_parent(&name) <= 0) name = NULL; - } else if (IN_SET(dns_transaction_key(t)->type, DNS_TYPE_SOA, DNS_TYPE_NS)) { - - type = DNS_TYPE_DS; - log_debug("Requesting DS (%s %s) to validate transaction %" PRIu16 " (%s, %s empty SOA/NS response).", - special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), name, t->id, name, signed_status); - - } else { - type = DNS_TYPE_SOA; - log_debug("Requesting SOA (%s %s) to validate transaction %" PRIu16 " (%s, %s empty non-SOA/NS/DS response).", - special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), name, t->id, name, signed_status); - } - if (name) { - _cleanup_(dns_resource_key_unrefp) DnsResourceKey *soa = NULL; + _cleanup_(dns_resource_key_unrefp) DnsResourceKey *ds = NULL; - soa = dns_resource_key_new(dns_transaction_key(t)->class, type, name); - if (!soa) + log_debug("Requesting DS (%s %s) to validate transaction %" PRIu16 " (%s empty response).", + special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), name, t->id, + dns_resource_key_name(dns_transaction_key(t))); + + ds = dns_resource_key_new(dns_transaction_key(t)->class, DNS_TYPE_DS, name); + if (!ds) return -ENOMEM; - r = dns_transaction_request_dnssec_rr(t, soa); + r = dns_transaction_request_dnssec_rr(t, ds); if (r < 0) return r; } @@ -2762,7 +2784,6 @@ DnsTransaction *dt; /* For SOA or NS RRs we look for a matching DS transaction */ - SET_FOREACH(dt, t->dnssec_transactions) { if (dns_transaction_key(dt)->class != rr->key->class) @@ -2770,7 +2791,7 @@ if (dns_transaction_key(dt)->type != DNS_TYPE_DS) continue; - r = dns_name_equal(dns_resource_key_name(dns_transaction_key(dt)), dns_resource_key_name(rr->key)); + r = dns_name_endswith(dns_resource_key_name(rr->key), dns_resource_key_name(dns_transaction_key(dt))); if (r < 0) return r; if (r == 0) @@ -2799,16 +2820,16 @@ DnsTransaction *dt; /* - * CNAME/DNAME RRs cannot be located at a zone apex, hence look directly for the parent SOA. + * CNAME/DNAME RRs cannot be located at a zone apex, hence look directly for the parent DS. * - * DS RRs are signed if the parent is signed, hence also look at the parent SOA + * DS RRs are signed if the parent is signed, hence also look at the parent DS */ SET_FOREACH(dt, t->dnssec_transactions) { if (dns_transaction_key(dt)->class != rr->key->class) continue; - if (dns_transaction_key(dt)->type != DNS_TYPE_SOA) + if (dns_transaction_key(dt)->type != DNS_TYPE_DS) continue; if (!parent) { @@ -2826,7 +2847,7 @@ } } - r = dns_name_equal(dns_resource_key_name(dns_transaction_key(dt)), parent); + r = dns_name_endswith(parent, dns_resource_key_name(dns_transaction_key(dt))); if (r < 0) return r; if (r == 0) @@ -2841,25 +2862,26 @@ default: { DnsTransaction *dt; - /* Any other kind of RR (including DNSKEY/NSEC/NSEC3). Let's see if our SOA lookup was authenticated */ + /* Any other kind of RR (including DNSKEY/NSEC/NSEC3). Let's see if our DS lookup was authenticated */ SET_FOREACH(dt, t->dnssec_transactions) { - if (dns_transaction_key(dt)->class != rr->key->class) continue; - if (dns_transaction_key(dt)->type != DNS_TYPE_SOA) + if (dns_transaction_key(dt)->type != DNS_TYPE_DS) continue; - r = dns_name_equal(dns_resource_key_name(dns_transaction_key(dt)), dns_resource_key_name(rr->key)); + r = dns_name_endswith(dns_resource_key_name(rr->key), dns_resource_key_name(dns_transaction_key(dt))); if (r < 0) return r; if (r == 0) continue; - /* We found the transaction that was supposed to find the SOA RR for us. It was - * successful, but found no RR for us. This means we are not at a zone cut. In this - * case, we require authentication if the SOA lookup was authenticated too. */ - return FLAGS_SET(dt->answer_query_flags, SD_RESOLVED_AUTHENTICATED); + if (!FLAGS_SET(dt->answer_query_flags, SD_RESOLVED_AUTHENTICATED)) + return false; + + /* We expect this to be signed when the DS record exists, and don't expect it to be + * signed when the DS record is proven not to exist. */ + return dns_answer_match_key(dt->answer, dns_transaction_key(dt), NULL); } return true; @@ -2929,7 +2951,6 @@ char key_str[DNS_RESOURCE_KEY_STRING_MAX]; DnsTransaction *dt; const char *name; - uint16_t type = 0; int r; assert(t); @@ -2964,43 +2985,37 @@ name = dns_resource_key_name(dns_transaction_key(t)); - if (dns_transaction_key(t)->type == DNS_TYPE_DS) { - - /* We got a negative reply for this DS lookup? DS RRs are signed when their parent zone is signed, - * hence check the parent SOA in this case. */ - + if (IN_SET(dns_transaction_key(t)->type, DNS_TYPE_DS, DNS_TYPE_CNAME, DNS_TYPE_DNAME)) { + /* We got a negative reply for this DS/CNAME/DNAME lookup? Check the parent in this case to + * see if this answer should have been signed. */ r = dns_name_parent(&name); if (r < 0) return r; if (r == 0) return true; + } - type = DNS_TYPE_SOA; - - } else if (IN_SET(dns_transaction_key(t)->type, DNS_TYPE_SOA, DNS_TYPE_NS)) - /* We got a negative reply for this SOA/NS lookup? If so, check if there's a DS RR for this */ - type = DNS_TYPE_DS; - else - /* For all other negative replies, check for the SOA lookup */ - type = DNS_TYPE_SOA; - - /* For all other RRs we check the SOA on the same level to see + /* For all other RRs we check the DS on the same level to see * if it's signed. */ SET_FOREACH(dt, t->dnssec_transactions) { - if (dns_transaction_key(dt)->class != dns_transaction_key(t)->class) continue; - if (dns_transaction_key(dt)->type != type) + if (dns_transaction_key(dt)->type != DNS_TYPE_DS) continue; - r = dns_name_equal(dns_resource_key_name(dns_transaction_key(dt)), name); + r = dns_name_endswith(name, dns_resource_key_name(dns_transaction_key(dt))); if (r < 0) return r; if (r == 0) continue; - return FLAGS_SET(dt->answer_query_flags, SD_RESOLVED_AUTHENTICATED); + if (!FLAGS_SET(dt->answer_query_flags, SD_RESOLVED_AUTHENTICATED)) + return false; + + /* We expect this to be signed when the DS record exists, and don't expect it to be signed + * when the DS record is proven not to exist. */ + return dns_answer_match_key(dt->answer, dns_transaction_key(dt), NULL); } /* If in doubt, require NSEC/NSEC3 */ diff -Nru systemd-252.23/src/resolve/resolved-dns-transaction.h systemd-252.24/src/resolve/resolved-dns-transaction.h --- systemd-252.23/src/resolve/resolved-dns-transaction.h 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/resolve/resolved-dns-transaction.h 2024-04-26 00:30:13.000000000 +0000 @@ -135,6 +135,11 @@ unsigned block_gc; + /* Set when we're willing to let this transaction live beyond it's usefulness for the original query, + * for caching purposes. This blocks gc while there is still a chance we might still receive an + * answer. */ + bool wait_for_answer; + LIST_FIELDS(DnsTransaction, transactions_by_scope); LIST_FIELDS(DnsTransaction, transactions_by_stream); LIST_FIELDS(DnsTransaction, transactions_by_key); diff -Nru systemd-252.23/src/resolve/resolved-dns-trust-anchor.c systemd-252.24/src/resolve/resolved-dns-trust-anchor.c --- systemd-252.23/src/resolve/resolved-dns-trust-anchor.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/resolve/resolved-dns-trust-anchor.c 2024-04-26 00:30:13.000000000 +0000 @@ -163,7 +163,15 @@ "private\0" /* Defined by RFC 8375. The most official choice. */ - "home.arpa\0"; + "home.arpa\0" + + /* RFC 8880 says because the 'ipv4only.arpa' zone has to + * be an insecure delegation, DNSSEC cannot be used to + * protect these answers from tampering by malicious + * devices on the path */ + "ipv4only.arpa\0" + "170.0.0.192.in-addr.arpa\0" + "171.0.0.192.in-addr.arpa\0"; const char *name; int r; diff -Nru systemd-252.23/src/resolve/resolved-mdns.c systemd-252.24/src/resolve/resolved-mdns.c --- systemd-252.23/src/resolve/resolved-mdns.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/resolve/resolved-mdns.c 2024-04-26 00:30:13.000000000 +0000 @@ -315,7 +315,7 @@ } DNS_ANSWER_FOREACH_ITEM(item, answer) { - DnsAnswerFlags flags = item->flags; + DnsAnswerFlags flags = item->flags | DNS_ANSWER_REFUSE_TTL_NO_MATCH; /* The cache-flush bit must not be set in legacy unicast responses. * See section 6.7 of RFC 6762. */ if (legacy_query) diff -Nru systemd-252.23/src/rpm/macros.systemd.in systemd-252.24/src/rpm/macros.systemd.in --- systemd-252.23/src/rpm/macros.systemd.in 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/rpm/macros.systemd.in 2024-04-26 00:30:13.000000000 +0000 @@ -13,6 +13,7 @@ %_udevhwdbdir {{UDEV_HWDB_DIR}} %_udevrulesdir {{UDEV_RULES_DIR}} %_journalcatalogdir {{SYSTEMD_CATALOG_DIR}} +%_kernel_install_dir {{KERNEL_INSTALL_DIR}} %_binfmtdir {{BINFMT_DIR}} %_sysctldir {{SYSCTL_DIR}} %_sysusersdir {{SYSUSERS_DIR}} diff -Nru systemd-252.23/src/shared/base-filesystem.c systemd-252.24/src/shared/base-filesystem.c --- systemd-252.23/src/shared/base-filesystem.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/shared/base-filesystem.c 2024-04-26 00:30:13.000000000 +0000 @@ -107,12 +107,12 @@ # else # error "Unknown RISC-V ABI" # endif -#elif defined(__s390__) - /* s390-linux-gnu */ #elif defined(__s390x__) { "lib64", 0, "usr/lib/"LIB_ARCH_TUPLE"\0" "usr/lib64\0", "ld-lsb-s390x.so.3" }, # define KNOW_LIB64_DIRS 1 +#elif defined(__s390__) + /* s390-linux-gnu */ #elif defined(__sparc__) #endif /* gcc doesn't allow pragma to be used within constructs, hence log about this separately below */ diff -Nru systemd-252.23/src/shared/blockdev-util.c systemd-252.24/src/shared/blockdev-util.c --- systemd-252.23/src/shared/blockdev-util.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/shared/blockdev-util.c 2024-04-26 00:30:13.000000000 +0000 @@ -11,6 +11,7 @@ #include "alloc-util.h" #include "blockdev-util.h" #include "btrfs-util.h" +#include "device-private.h" #include "device-util.h" #include "devnum-util.h" #include "dirent-util.h" @@ -397,24 +398,36 @@ } int blockdev_partscan_enabled(int fd) { - _cleanup_free_ char *p = NULL, *buf = NULL; - unsigned long long ull; - struct stat st; - int r; - - /* Checks if partition scanning is correctly enabled on the block device */ + _cleanup_(sd_device_unrefp) sd_device *dev = NULL; + unsigned capability; + int r, ext_range; - if (fstat(fd, &st) < 0) - return -errno; + /* Checks if partition scanning is correctly enabled on the block device. + * + * The 'GENHD_FL_NO_PART_SCAN' flag was introduced by + * https://github.com/torvalds/linux/commit/d27769ec3df1a8de9ca450d2dcd72d1ab259ba32 (v3.2). + * But at that time, the flag is also effectively implied when 'minors' element of 'struct gendisk' + * is 1, which can be check with 'ext_range' sysfs attribute. Explicit flag ('GENHD_FL_NO_PART_SCAN') + * can be obtained from 'capability' sysattr. + * + * With https://github.com/torvalds/linux/commit/1ebe2e5f9d68e94c524aba876f27b945669a7879 (v5.17), we + * can check the flag from 'ext_range' sysfs attribute directly. + * + * With https://github.com/torvalds/linux/commit/e81cd5a983bb35dabd38ee472cf3fea1c63e0f23 (v6.3), + * the 'capability' sysfs attribute is deprecated, hence we cannot check the flag from it. + * + * To support both old and new kernels, we need to do the following: first check 'ext_range' sysfs + * attribute, and if '1' we can conclude partition scanning is disabled, otherwise check 'capability' + * sysattr for older version. */ - if (!S_ISBLK(st.st_mode)) - return -ENOTBLK; + assert(fd >= 0); - if (asprintf(&p, "/sys/dev/block/%u:%u/capability", major(st.st_rdev), minor(st.st_rdev)) < 0) - return -ENOMEM; + r = block_device_new_from_fd(fd, 0, &dev); + if (r < 0) + return r; - r = read_one_line_file(p, &buf); - if (r == -ENOENT) /* If the capability file doesn't exist then we are most likely looking at a + r = device_get_sysattr_int(dev, "ext_range", &ext_range); + if (r == -ENOENT) /* If the ext_range file doesn't exist then we are most likely looking at a * partition block device, not the whole block device. And that means we have no * partition scanning on for it (we do for its parent, but not for the partition * itself). */ @@ -422,7 +435,13 @@ if (r < 0) return r; - r = safe_atollu_full(buf, 16, &ull); + if (ext_range <= 1) /* The valus should be always positive, but the kernel uses '%d' for the + * attribute. Let's gracefully handle zero or negative. */ + return false; + + r = device_get_sysattr_unsigned_full(dev, "capability", 16, &capability); + if (r == -ENOENT) + return false; if (r < 0) return r; @@ -430,7 +449,12 @@ #define GENHD_FL_NO_PART_SCAN (0x0200) #endif - return !FLAGS_SET(ull, GENHD_FL_NO_PART_SCAN); + /* If 0x200 is set, part scanning is definitely off. */ + if (FLAGS_SET(capability, GENHD_FL_NO_PART_SCAN)) + return false; + + /* Otherwise, assume part scanning is on, we have no further checks available. Assume the best. */ + return true; } static int blockdev_is_encrypted(const char *sysfs_path, unsigned depth_left) { diff -Nru systemd-252.23/src/shared/bpf-dlopen.c systemd-252.24/src/shared/bpf-dlopen.c --- systemd-252.23/src/shared/bpf-dlopen.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/shared/bpf-dlopen.c 2024-04-26 00:30:13.000000000 +0000 @@ -60,11 +60,15 @@ return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "neither libbpf.so.1 nor libbpf.so.0 are installed: %s", dlerror()); + log_debug("Loaded 'libbpf.so.0' via dlopen()"); + /* symbols deprecated in 1.0 we use as compat */ r = dlsym_many_or_warn(dl, LOG_DEBUG, DLSYM_ARG(bpf_create_map), DLSYM_ARG(bpf_probe_prog_type)); } else { + log_debug("Loaded 'libbpf.so.1' via dlopen()"); + /* symbols available from 0.7.0 */ r = dlsym_many_or_warn(dl, LOG_DEBUG, DLSYM_ARG(bpf_map_create), diff -Nru systemd-252.23/src/shared/copy.c systemd-252.24/src/shared/copy.c --- systemd-252.23/src/shared/copy.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/shared/copy.c 2024-04-26 00:30:13.000000000 +0000 @@ -304,7 +304,7 @@ if (try_cfr) { n = try_copy_file_range(fdf, NULL, fdt, NULL, m, 0u); if (n < 0) { - if (!IN_SET(n, -EINVAL, -ENOSYS, -EXDEV, -EBADF)) + if (!IN_SET(n, -EINVAL, -ENOSYS, -EXDEV, -EBADF, -EOPNOTSUPP)) return n; try_cfr = false; diff -Nru systemd-252.23/src/shared/dlfcn-util.c systemd-252.24/src/shared/dlfcn-util.c --- systemd-252.23/src/shared/dlfcn-util.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/shared/dlfcn-util.c 2024-04-26 00:30:13.000000000 +0000 @@ -49,6 +49,8 @@ return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "%s is not installed: %s", filename, dlerror()); + log_debug("Loaded '%s' via dlopen()", filename); + va_list ap; va_start(ap, log_level); r = dlsym_many_or_warnv(dl, log_level, ap); diff -Nru systemd-252.23/src/shared/idn-util.c systemd-252.24/src/shared/idn-util.c --- systemd-252.23/src/shared/idn-util.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/shared/idn-util.c 2024-04-26 00:30:13.000000000 +0000 @@ -50,7 +50,10 @@ if (!dl) return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libidn support is not installed: %s", dlerror()); - } + log_debug("Loaded 'libidn.so.11' via dlopen()"); + } else + log_debug("Loaded 'libidn.so.12' via dlopen()"); + r = dlsym_many_or_warn( dl, diff -Nru systemd-252.23/src/shared/install.c systemd-252.24/src/shared/install.c --- systemd-252.23/src/shared/install.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/shared/install.c 2024-04-26 00:30:13.000000000 +0000 @@ -342,9 +342,12 @@ assert(verb || r >= 0); for (size_t i = 0; i < n_changes; i++) { - if (changes[i].type < 0) - assert(verb); assert(changes[i].path); + /* This tries to tell the compiler that it's safe to use 'verb' in a string format if there + * was an error, but the compiler doesn't care and fails anyway, so strna(verb) is used + * too. */ + assert(verb || changes[i].type >= 0); + verb = strna(verb); /* When making changes here, make sure to also change install_error() in dbus-manager.c. */ diff -Nru systemd-252.23/src/shared/tpm2-util.c systemd-252.24/src/shared/tpm2-util.c --- systemd-252.23/src/shared/tpm2-util.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/shared/tpm2-util.c 2024-04-26 00:30:13.000000000 +0000 @@ -199,6 +199,8 @@ if (!dl) return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), "Failed to load %s: %s", fn, dlerror()); + log_debug("Loaded '%s' via dlopen()", fn); + func = dlsym(dl, TSS2_TCTI_INFO_SYMBOL); if (!func) return log_error_errno(SYNTHETIC_ERRNO(ENOTRECOVERABLE), diff -Nru systemd-252.23/src/shared/verbs.c systemd-252.24/src/shared/verbs.c --- systemd-252.23/src/shared/verbs.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/shared/verbs.c 2024-04-26 00:30:13.000000000 +0000 @@ -13,22 +13,21 @@ #include "verbs.h" #include "virt.h" -/* Wraps running_in_chroot() which is used in various places, but also adds an environment variable check so external - * processes can reliably force this on. - */ +/* Wraps running_in_chroot() which is used in various places, but also adds an environment variable check + * so external processes can reliably force this on. */ bool running_in_chroot_or_offline(void) { int r; - /* Added to support use cases like rpm-ostree, where from %post scripts we only want to execute "preset", but - * not "start"/"restart" for example. + /* Added to support use cases like rpm-ostree, where from %post scripts we only want to execute "preset", + * but not "start"/"restart" for example. * * See docs/ENVIRONMENT.md for docs. */ r = getenv_bool("SYSTEMD_OFFLINE"); - if (r < 0 && r != -ENXIO) - log_debug_errno(r, "Failed to parse $SYSTEMD_OFFLINE: %m"); - else if (r >= 0) + if (r >= 0) return r > 0; + if (r != -ENXIO) + log_debug_errno(r, "Failed to parse $SYSTEMD_OFFLINE, ignoring: %m"); /* We've had this condition check for a long time which basically checks for legacy chroot case like Fedora's * "mock", which is used for package builds. We don't want to try to start systemd services there, since @@ -40,8 +39,7 @@ */ r = running_in_chroot(); if (r < 0) - log_debug_errno(r, "running_in_chroot(): %m"); - + log_debug_errno(r, "Failed to check if we're running in chroot, assuming not: %m"); return r > 0; } diff -Nru systemd-252.23/src/shared/watchdog.c systemd-252.24/src/shared/watchdog.c --- systemd-252.23/src/shared/watchdog.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/shared/watchdog.c 2024-04-26 00:30:13.000000000 +0000 @@ -95,7 +95,7 @@ governor, WRITE_STRING_FILE_DISABLE_BUFFER | WRITE_STRING_FILE_VERIFY_ON_FAILURE | WRITE_STRING_FILE_VERIFY_IGNORE_NEWLINE); if (r < 0) - return log_error_errno(r, "Failed to set pretimeout_governor to '%s': %m", governor); + return log_error_errno(r, "Failed to set watchdog pretimeout_governor to '%s': %m", governor); return r; } @@ -157,7 +157,7 @@ if (ioctl(watchdog_fd, WDIOC_GETPRETIMEOUT, &sec) < 0) { watchdog_pretimeout = 0; - return log_full_errno(ERRNO_IS_NOT_SUPPORTED(errno) ? LOG_DEBUG : LOG_WARNING, errno, "Failed to get pretimeout value, ignoring: %m"); + return log_full_errno(ERRNO_IS_NOT_SUPPORTED(errno) ? LOG_DEBUG : LOG_WARNING, errno, "Failed to get watchdog pretimeout value, ignoring: %m"); } watchdog_pretimeout = sec * USEC_PER_SEC; @@ -181,7 +181,7 @@ return 0; } - return log_error_errno(errno, "Failed to set pretimeout to %s: %m", FORMAT_TIMESPAN(sec, USEC_PER_SEC)); + return log_error_errno(errno, "Failed to set watchdog pretimeout to %s: %m", FORMAT_TIMESPAN(sec, USEC_PER_SEC)); } /* The set ioctl does not return the actual value set so get it now. */ @@ -274,10 +274,10 @@ r = watchdog_set_timeout(); if (r < 0) { if (!ERRNO_IS_NOT_SUPPORTED(r)) - return log_error_errno(r, "Failed to set timeout to %s: %m", + return log_error_errno(r, "Failed to set watchdog hardware timeout to %s: %m", FORMAT_TIMESPAN(watchdog_timeout, 0)); - log_info("Modifying watchdog timeout is not supported, reusing the programmed timeout."); + log_info("Modifying watchdog hardware timeout is not supported, reusing the programmed timeout."); watchdog_timeout = USEC_INFINITY; } } @@ -286,8 +286,8 @@ r = watchdog_read_timeout(); if (r < 0) { if (!ERRNO_IS_NOT_SUPPORTED(r)) - return log_error_errno(r, "Failed to query watchdog HW timeout: %m"); - log_info("Reading watchdog timeout is not supported, reusing the configured timeout."); + return log_error_errno(r, "Failed to query watchdog hardware timeout: %m"); + log_info("Reading watchdog hardware timeout is not supported, reusing the configured timeout."); watchdog_timeout = previous_timeout; } } @@ -302,7 +302,7 @@ if (r < 0) return r; - log_info("Watchdog running with a timeout of %s.", FORMAT_TIMESPAN(watchdog_timeout, 0)); + log_info("Watchdog running with a hardware timeout of %s.", FORMAT_TIMESPAN(watchdog_timeout, 0)); return watchdog_ping_now(); } diff -Nru systemd-252.23/src/systemctl/systemctl-logind.c systemd-252.24/src/systemctl/systemctl-logind.c --- systemd-252.23/src/systemctl/systemctl-logind.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/systemctl/systemctl-logind.c 2024-04-26 00:30:13.000000000 +0000 @@ -363,7 +363,7 @@ return r; if (isempty(action)) - return log_error_errno(SYNTHETIC_ERRNO(ENODATA), "No scheduled shutdown."); + return log_full_errno(arg_quiet ? LOG_DEBUG : LOG_ERR, SYNTHETIC_ERRNO(ENODATA), "No scheduled shutdown."); if (STR_IN_SET(action, "halt", "poweroff", "exit")) action = "Shutdown"; diff -Nru systemd-252.23/src/systemd/sd-bus-vtable.h systemd-252.24/src/systemd/sd-bus-vtable.h --- systemd-252.23/src/systemd/sd-bus-vtable.h 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/systemd/sd-bus-vtable.h 2024-04-26 00:30:13.000000000 +0000 @@ -208,6 +208,7 @@ _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \ NAME, ...) NAME +#define _SD_VARARGS_FOREACH_EVEN_00(FN) #define _SD_VARARGS_FOREACH_EVEN_01(FN, X) FN(X) #define _SD_VARARGS_FOREACH_EVEN_02(FN, X, Y) FN(X) #define _SD_VARARGS_FOREACH_EVEN_04(FN, X, Y, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_02(FN, __VA_ARGS__) @@ -261,9 +262,11 @@ _SD_VARARGS_FOREACH_EVEN_08, _SD_VARARGS_FOREACH_EVEN_07, \ _SD_VARARGS_FOREACH_EVEN_06, _SD_VARARGS_FOREACH_EVEN_05, \ _SD_VARARGS_FOREACH_EVEN_04, _SD_VARARGS_FOREACH_EVEN_03, \ - _SD_VARARGS_FOREACH_EVEN_02, _SD_VARARGS_FOREACH_EVEN_01) \ + _SD_VARARGS_FOREACH_EVEN_02, _SD_VARARGS_FOREACH_EVEN_01, \ + _SD_VARARGS_FOREACH_EVEN_00) \ (FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_ODD_00(FN) #define _SD_VARARGS_FOREACH_ODD_01(FN, X) #define _SD_VARARGS_FOREACH_ODD_02(FN, X, Y) FN(Y) #define _SD_VARARGS_FOREACH_ODD_04(FN, X, Y, ...) FN(Y) _SD_VARARGS_FOREACH_ODD_02(FN, __VA_ARGS__) @@ -317,7 +320,8 @@ _SD_VARARGS_FOREACH_ODD_08, _SD_VARARGS_FOREACH_ODD_07, \ _SD_VARARGS_FOREACH_ODD_06, _SD_VARARGS_FOREACH_ODD_05, \ _SD_VARARGS_FOREACH_ODD_04, _SD_VARARGS_FOREACH_ODD_03, \ - _SD_VARARGS_FOREACH_ODD_02, _SD_VARARGS_FOREACH_ODD_01) \ + _SD_VARARGS_FOREACH_ODD_02, _SD_VARARGS_FOREACH_ODD_01, \ + _SD_VARARGS_FOREACH_ODD_00) \ (FN, __VA_ARGS__) #define SD_BUS_ARGS(...) __VA_ARGS__ diff -Nru systemd-252.23/src/userdb/userdbctl.c systemd-252.24/src/userdb/userdbctl.c --- systemd-252.23/src/userdb/userdbctl.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/userdb/userdbctl.c 2024-04-26 00:30:13.000000000 +0000 @@ -309,6 +309,9 @@ assert(table); assert(add_unavailable); + if (!p) + return 0; + for (size_t i = 0; p && i < p->n_entries; i++) { UidRangeEntry *x = p->entries + i; @@ -533,7 +536,8 @@ for (size_t i = 0; i < ELEMENTSOF(uid_range_table); i++) { _cleanup_free_ char *name = NULL, *comment = NULL; - if (!uid_range_covers(p, uid_range_table[i].first, uid_range_table[i].last)) + if (!uid_range_covers(p, uid_range_table[i].first, + uid_range_table[i].last - uid_range_table[i].first + 1)) continue; name = strjoin(special_glyph(SPECIAL_GLYPH_ARROW_DOWN), diff -Nru systemd-252.23/src/userdb/userdbd-manager.c systemd-252.24/src/userdb/userdbd-manager.c --- systemd-252.23/src/userdb/userdbd-manager.c 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/src/userdb/userdbd-manager.c 2024-04-26 00:30:13.000000000 +0000 @@ -4,6 +4,7 @@ #include "sd-daemon.h" +#include "env-util.h" #include "fd-util.h" #include "fs-util.h" #include "mkdir.h" @@ -158,7 +159,6 @@ if (r < 0) return log_error_errno(r, "Failed to fork new worker child: %m"); if (r == 0) { - char pids[DECIMAL_STR_MAX(pid_t)]; /* Child */ log_close(); @@ -186,9 +186,9 @@ safe_close(m->listen_fd); } - xsprintf(pids, PID_FMT, pid); - if (setenv("LISTEN_PID", pids, 1) < 0) { - log_error_errno(errno, "Failed to set $LISTEN_PID: %m"); + r = setenvf("LISTEN_PID", /* overwrite= */ true, PID_FMT, pid); + if (r < 0) { + log_error_errno(r, "Failed to set $LISTEN_PID: %m"); _exit(EXIT_FAILURE); } diff -Nru systemd-252.23/test/TEST-69-SHUTDOWN/test.sh systemd-252.24/test/TEST-69-SHUTDOWN/test.sh --- systemd-252.23/test/TEST-69-SHUTDOWN/test.sh 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/test/TEST-69-SHUTDOWN/test.sh 2024-04-26 00:30:13.000000000 +0000 @@ -32,6 +32,7 @@ EOF inst /usr/bin/screen echo "PS1='screen\$WINDOW # '" >>"$workspace/root/.bashrc" + echo "TERM=linux" >>"$workspace/root/.bash_profile" echo 'startup_message off' >"$workspace/etc/screenrc" echo 'bell_msg ""' >>"$workspace/etc/screenrc" } diff -Nru systemd-252.23/test/test-network/systemd-networkd-tests.py systemd-252.24/test/test-network/systemd-networkd-tests.py --- systemd-252.23/test/test-network/systemd-networkd-tests.py 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/test/test-network/systemd-networkd-tests.py 2024-04-26 00:30:13.000000000 +0000 @@ -3116,6 +3116,7 @@ print(output) self.assertRegex(output, 'inet6 .* scope link') + @unittest.skip("Re-enable once https://github.com/systemd/systemd/issues/30056 is resolved") def test_sysctl(self): copy_network_unit('25-sysctl.network', '12-dummy.netdev') start_networkd() diff -Nru systemd-252.23/test/test-shutdown.py systemd-252.24/test/test-shutdown.py --- systemd-252.23/test/test-shutdown.py 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/test/test-shutdown.py 2024-04-26 00:30:13.000000000 +0000 @@ -11,18 +11,21 @@ def run(args): - ret = 1 logger = logging.getLogger("test-shutdown") + logfile = None + + if args.logfile: + logger.debug("Logging pexpect IOs to %s", args.logfile) + logfile = open(args.logfile, 'w') + elif args.verbose: + logfile = sys.stdout logger.info("spawning test") - console = pexpect.spawn(args.command, args.arg, env={ - "TERM": "linux", + console = pexpect.spawn(args.command, args.arg, logfile=logfile, env={ + "TERM": "dumb", }, encoding='utf-8', timeout=60) - if args.verbose: - console.logfile = sys.stdout - logger.debug("child pid %d", console.pid) try: @@ -38,12 +41,16 @@ console.send('c') console.expect('screen1 ', 10) + logger.info('wait for the machine to fully boot') + console.sendline('systemctl is-system-running --wait') + console.expect(r'\b(running|degraded)\b', 60) + # console.interact() console.sendline('tty') console.expect(r'/dev/(pts/\d+)') pty = console.match.group(1) - logger.info("window 1 at line %s", pty) + logger.info("window 1 at tty %s", pty) logger.info("schedule reboot") console.sendline('shutdown -r') @@ -100,6 +107,7 @@ def main(): parser = argparse.ArgumentParser(description='test logind shutdown feature') parser.add_argument("-v", "--verbose", action="store_true", help="verbose") + parser.add_argument("--logfile", metavar='FILE', help="Save all test input/output to the given path") parser.add_argument("command", help="command to run") parser.add_argument("arg", nargs='*', help="args for command") diff -Nru systemd-252.23/test/units/testsuite-72.sh systemd-252.24/test/units/testsuite-72.sh --- systemd-252.23/test/units/testsuite-72.sh 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/test/units/testsuite-72.sh 2024-04-26 00:30:13.000000000 +0000 @@ -12,6 +12,15 @@ exit 0 fi +# Loopback devices may not be supported. They are used because sfdisk cannot +# change the sector size of a file, and we want to test both 512 and 4096 byte +# sectors. If loopback devices are not supported, we can only test one sector +# size, and the underlying device is likely to have a sector size of 512 bytes. +if [[ ! -e /dev/loop-control ]]; then + echo "No loopback device support" + SECTOR_SIZES="512" +fi + export SYSTEMD_PAGER=cat export SYSTEMD_LOG_LEVEL=debug diff -Nru systemd-252.23/tmpfiles.d/systemd.conf.in systemd-252.24/tmpfiles.d/systemd.conf.in --- systemd-252.23/tmpfiles.d/systemd.conf.in 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/tmpfiles.d/systemd.conf.in 2024-04-26 00:30:13.000000000 +0000 @@ -9,7 +9,7 @@ d /run/user 0755 root root - {% if ENABLE_UTMP %} -F! /run/utmp 0664 root utmp - +f+! /run/utmp 0664 root utmp - {% endif %} d /run/systemd/ask-password 0755 root root - @@ -26,16 +26,13 @@ {% if HAVE_ACL %} {% if ENABLE_ADM_GROUP and ENABLE_WHEEL_GROUP %} a+ /run/log/journal - - - - d:group::r-x,d:group:adm:r-x,d:group:wheel:r-x,group::r-x,group:adm:r-x,group:wheel:r-x -a+ /run/log/journal/%m - - - - d:group:adm:r-x,d:group:wheel:r-x,group:adm:r-x,group:wheel:r-x -a+ /run/log/journal/%m/*.journal* - - - - group:adm:r--,group:wheel:r-- +A+ /run/log/journal/%m - - - - d:group:adm:r-x,d:group:wheel:r-x,group:adm:r-X,group:wheel:r-X {% elif ENABLE_ADM_GROUP %} a+ /run/log/journal - - - - d:group::r-x,d:group:adm:r-x,group::r-x,group:adm:r-x -a+ /run/log/journal/%m - - - - d:group:adm:r-x,group:adm:r-x -a+ /run/log/journal/%m/*.journal* - - - - group:adm:r-- +A+ /run/log/journal/%m - - - - d:group:adm:r-x,group:adm:r-X {% elif ENABLE_WHEEL_GROUP %} a+ /run/log/journal - - - - d:group::r-x,d:group:wheel:r-x,group::r-x,group:wheel:r-x -a+ /run/log/journal/%m - - - - d:group:wheel:r-x,group:wheel:r-x -a+ /run/log/journal/%m/*.journal* - - - - group:wheel:r-- +A+ /run/log/journal/%m - - - - d:group:wheel:r-x,group:wheel:r-X {% endif %} {% endif %} diff -Nru systemd-252.23/units/systemd-journal-upload.service.in systemd-252.24/units/systemd-journal-upload.service.in --- systemd-252.23/units/systemd-journal-upload.service.in 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/units/systemd-journal-upload.service.in 2024-04-26 00:30:13.000000000 +0000 @@ -27,8 +27,6 @@ ProtectKernelModules=yes ProtectKernelTunables=yes Restart=on-failure -RestartSteps=10 -RestartMaxDelaySec=60 RestrictAddressFamilies=AF_UNIX AF_INET AF_INET6 RestrictNamespaces=yes RestrictRealtime=yes diff -Nru systemd-252.23/units/systemd-modules-load.service.in systemd-252.24/units/systemd-modules-load.service.in --- systemd-252.23/units/systemd-modules-load.service.in 2024-02-28 16:57:11.000000000 +0000 +++ systemd-252.24/units/systemd-modules-load.service.in 2024-04-26 00:30:13.000000000 +0000 @@ -20,7 +20,9 @@ ConditionDirectoryNotEmpty=|/etc/modules-load.d ConditionDirectoryNotEmpty=|/run/modules-load.d ConditionKernelCommandLine=|modules-load +ConditionKernelCommandLine=|modules_load ConditionKernelCommandLine=|rd.modules-load +ConditionKernelCommandLine=|rd.modules_load [Service] Type=oneshot