shared/bus-unit-util: fix PrivateTmp=/PrivateUsers=/ProtectControlGroups= and Ex variants
For some fields, we perform careful parsing and verification on the sender
side. For other fields, we accept any string or strv. I think that actually
this is fine: we should optimize for the correct case, i.e. the user runs a
command that is valid. The server must perform parsing in all cases, so doing
the verification on the sender side doesn't add value. When doing parsing
locally, in case of invalid or unsupported input, we would generate the error
message locally, so we would avoid the D-Bus call, but the message itself is
not better and from the user's point of view, the result is the same. And by
doing the parsing only on the server side, we deal better with the case where
the sender has an older version of the software. By not doing verification, we
implicitly "support" new values. And when the sender has a newer version that
supports additional fields, that does not help as long as the server uses an
older version. So in case of version mismatches, parsing on the server side is
as good or better.
shared/bus-unit-util: tweak bus_append_exec_command to use Ex prop only if necessary
This changes little in behaviour, the conceptual part is more important. The
non-Ex variant is the actual name on the command line, and we should use the
non-Ex D-Bus property too, if it works. This increases compatibility with old
versions. But the code was mostly doing the right thing. Even the tests tested
the right thing.
We generally want to have error messages with a fixed structure that convey the
important information, i.e. field name, error value, and the offending text for
options that take short values. (The text is not printed for strings encoded with
base64 and hexmem or for credentials.)
Let's use a helper that prints the message in a fixed format in the majority of
cases. In the few places where a custom message is useful, the helper is not
used. The helper:
- prints the field name, value, and error info,
- quotes the value,
- handles -ENOMEM, so we don't need to handle it separately everywhere.
When this code was originally written, parse functions would return -1
as error. Nowadays day all return a good errno, so it is fine if we print
the corresponding strerror.
shared/bus-unit-util: tweak error handling in bus_append_exec_command
exec_command_flags_to_strv() should not fail, unless we screwed up, so assert
instead of returning an error. Also, no need to strdup constant _PATH_BSHELL;
drop that so that we can get rid of the oom error handling. Finally, rename
l → cmdline for clarity.
shared/bus-unit-util: also send empty array for LogFilterPatterns=
Before, for empty input, we'd send an array with one item with an empty
pattern. Use the helper which sends an empty array instead.
bus_exec_context_set_transient_property() ignores items with an empty
pattern, so the result should be the same.
Request in review:
https://github.com/systemd/systemd/pull/37665#discussion_r2182375988.
test-bus-unit-util: add a test that attempts to serialize all know transient settings
The samples were partially generated using claude.ai. Those examples are
usually fairly boring. I tried to remove obvious repetitions and add some more
interesting examples, but certainly more edge cases could be added.
In some cases, we are quite lenient and do almost no verification on the sender
side.
ukify: when decompressing kernel before signing, call verify on decompressed file
Otherwise it will fail as it's an archive, not a PE file:
Invalid DOS header magic
Can't open image /boot/vmlinuz.old
/boot/vmlinuz.old is compressed and cannot be loaded by UEFI, decompressing
+ sbverify --list /boot/vmlinuz.old
=========================== short test summary info ============================
FAILED ../src/ukify/test/test_ukify.py::test_efi_signing_sbsign[3650] - subprocess.CalledProcessError: Command '['sbverify', '--list', PosixPath('/boot/vmlinuz.old')]' returned non-zero exit status 1.
FAILED ../src/ukify/test/test_ukify.py::test_efi_signing_sbsign[None] - subprocess.CalledProcessError: Command '['sbverify', '--list', PosixPath('/boot/vmlinuz.old')]' returned non-zero exit status 1.
FAILED ../src/ukify/test/test_ukify.py::test_inspect - subprocess.CalledProcessError: Command '['sbverify', '--list', PosixPath('/boot/vmlinuz.old')]' returned non-zero exit status 1.
pcrlock: process components outside of location window properly
So far, when we tried to match a component to eent log entries we
skipped those components if they were outside of our location window.
That however is too aggressive, since it means any components that are
already in the logs, but outside of the location window will be
considered unrecognized in the logs, and thus removed from the PCR
policy.
Change things around: always try to match up all components, regardless
if inside the location window or outside, but then make it non-fatal we
can't find a component outside of the location window.
As it turns out open() with O_PATH does *not* trigger autofs, you get a
reference to the autofs inode, if not triggered.
But there's a way out: open_tree() (when specified without
OPEN_TREE_CLONE) is actually fully equivalent to open() with O_PATH –
with the exception of one thing: it *does* trigger automounts.
Thanks for Christian Brauner for pointing me to this and saving my day.
openssl-util: allow to build with openssl without UI support (#38041)
This makes it possible to build systemd with
-Dc_args='-DOPENSSL_NO_UI_CONSOLE=1'. Hopefully, now systemd can be
built with other openssl implementations, like BoringSSL, which deos not
support UIs.
Those are user-controlled strings, so let's use heap allocations in the usual
fashion. (Though, with strndupa_safe, the allocations were bounded anyway, so
ultimately this doesn't matter.)
The zsh completions only complete one type argument, even though multiple
args are allowed. But the same issue occurs with other completions, e.g.
for options. I don't know how to solve this.
Those lists were partially wrong and partially outdated. We should generate
this document automatically, but let's revisit this topic after the conversion
to sphinx. For now, as a stop-gap solution, I generated the lists from
the new 'systemd-analyze transient-settings' command.
Related to https://github.com/systemd/systemd/pull/37641.
The name "transient settings" was used in docs/TRANSIENT-SETTINGS.md.
Using "setting" helps distinguish this from D-Bus "properties", which are
a much larger set, partially overlapping.
bus_append_unit_property() and associated functions accept a long list of
properties. But the specific names are only available through code. But it is
useful to be able to know the specific list of properties that is supported, in
particular for shell completions. Thus, add a way to list the properties that
are supported by the code.
In the future we could also turn this into a test for the documentation. For
various reasons, the list of properties listed in the docs is a partially
overlapping set. E.g. for service type, the pull request
https://github.com/systemd/systemd/pull/37661 creates a list with 212 entries,
and this code generates 7 entries less and 184 more. I didn't check all the
differences, but in the few cases I did, the list generated here was actually
correctly supported by 'systemd-run -p'.
test: drop ProtectHostnameEx, add one test for ProtectHostnameEx
This is a separate commit because the parent commit is supposed to be
backward compatible, i.e. the tests must pass with both the bogus ProtectHostnameEx
name and ProtectHostname.
A test is added for ProtectHostnameEx to verify that it is still accepted
for backward compat.
Accept ProtectHostname=… with the new extended syntax, keep accepting
ProtectHostnameEx=… for compat with release v257. Prefer sending ProtectHostname.
Currently, when running "systemctl preset-all --root=xxx" in mkosi
to enable/disable units for initrds, the system presets are used.
The problem with this approach is that the system presets are written
for the system, and that is not necessarily ideal for an initrd, but we
still want to use the same packages in the initrd that we install in the
system, so let's introduce a separate directory for initrd presets which
is used to pick up preset files from when we detect that we're configuring
an initrd (by looking for /etc/initrd-release).
We also introduce a systemd preset file for the initrd, which is based on
the system one, except with all the stuff unnecessary for the initrd removed.
Follow-up for dbef4dd4f23517abfc73b35f0bdf004d2f8f4805. Everything that that
commit says is true, but — at least for me — it wasn't obvious why the code is
correct and we can do fixed-size allocations like new(struct inotify_data, 1).
In sd_event_source.child, we have 5 bools. If we make them each take one byte,
the structure size increases. So let's do that for the three of them, and leave
the other two (less frequently used) squished into the last byte. This allows
more efficient code to be generated, without changing the size of the struct:
sd-event: drop some bitfield specifiers from struct sd_event_source
This does not change the size of the structure, because the size is determined
by .child, which has a 128-byte siginfo_t field. But by dropping the specifiers
we let the compiler generate code that operates on full bytes instead of having
to play with bitmasks, see second diff below.
Also move the bools in .memory_pressure into a gap to save a few bytes on
initialization.
openssl-util: allow to build with openssl without UI support
When OpenSSL is built without UI support, OPENSSL_NO_UI_CONSOLE is
defined. Or, even openssl is built with UI support, people may want to
build systemd without using OpenSSL's UI feature by specifying
-Dc_args='-DOPENSSL_NO_UI_CONSOLE=1'. This adds support for such cases.
Not tested, but hopefully, now systemd can be built with other ssl library,
like BoringSSL, which deos not support UIs.
We're still discussing whether we want to remove this or not, but
regardless of whether we end up removing it or not, it's something
we add ourselves and as such should not live in our headers that
override glibc headers, so let's move it to fd-util.h.
fd-util: Move RAW_O_LARGEFILE definition to fd-util.h
This is not something that comes from glibc, but which we invent
ourselves. As such, it should not be part of our overrides of glibc
headers, but instead should be part of one of our own headers, so
let's move it to fd-util.h.
Daan De Meyer [Mon, 30 Jun 2025 11:41:04 +0000 (13:41 +0200)]
test: Add tests for various varlink socket units
Let's make sure these socket units work as expected by stopping the
related services and making sure the services are started as expected
when a client connects to the corresponding socket.
Daan De Meyer [Mon, 30 Jun 2025 11:06:46 +0000 (13:06 +0200)]
udev: Fix initializing varlink server from listen fd
manager_listen_fds() instructs sd_listen_fds_with_names() to unset
the environment which means that when sd_varlink_server_listen_auto()
is called from manager_start_varlink_server(), when it eventually calls
sd_listen_fds_with_names() it will return zero because the environment
has already been unset in manager_listen_fds().
Fix the issue by not using sd_varlink_server_listen_auto() but instead
keeping track of the varlink socket in manager_listen_fds() and returning
it and passing it to manager_start_varlink_server().
shared/bus-unit-util: add helper for ImportCredentialEx= and fix naming confusion
We add D-Bus properties like "*Ex" because we cannot change the D-Bus property
type without breaking backward comapatibility. But those names are only for
D-Bus, not for config file stanzas or the command-line parser. There, we can
change the type, or in other words, there is no type, just a free-form string
whose interpretation we can extend or change. Commit 831f208783aeac443e6f2fc2efc3119535a032ef that added ProtectHostnameEx was
confused, because it added ImportCredentialEx in places where parsing of
ImportCredential should be have been extended.
On D-Bus, we send ImportCrednential in preference, and ImportCredentialEx only
when required. This way we send less bytes on the wire and support older
systems that don't understand the new property.