Commit Graph
90299 Commits
Author SHA1 Message Date
Yu Watanabe d26da0a705 crypto-util: make OpenSSL UI API symbols optional during dlopen
Previously, if systemd was built with OpenSSL UI support, it would fail
to load libcrypto at runtime if the library lacked UI support, requiring
a recompilation of systemd to fix.

Let's relax this strict requirement by making the UI methods optional
during dlopen(). openssl_ui_supported() is added to dynamically check
if all required UI symbols were successfully loaded.
2026-07-03 03:02:57 +09:00
Yu Watanabe 805f8c6503 crypto-util: allow loading private keys from engine/provider without UI support
OpenSSL UI is not a mandatory feature to load private keys from an engine
or a provider. Let's allow loading private keys even if OpenSSL UI is not
supported.

Note that even if OPENSSL_NO_UI_CONSOLE is set, the type UI_METHOD is
always defined. Hence, the `#ifndef` condition in the definition of
struct OpenSSLAskPasswordUI is unnecessary and can be dropped.
2026-07-03 03:02:57 +09:00
Yu Watanabe f63cc9af18 crypto-util: drop redundant logs
The called functions already log errors internally.
2026-07-03 03:02:56 +09:00
Yu Watanabe 7301e2602d crypto-util: move functions
Implementations for loading private/public keys and X.509 certificates
were scattered. Group them together to improve readability.
2026-07-03 03:02:56 +09:00
Yu Watanabe 7c21061f09 crypto-util: make OpenSSL ENGINE API symbols optional during dlopen
If systemd is compiled with OpenSSL 3 headers but executed in an environment
where OpenSSL 4 (libcrypto.so.4) is loaded, dlopen_many_sym_or_warn() will
fail because OpenSSL 4 completely removes the deprecated ENGINE API. This
breaks the ability to dynamically fallback and seamlessly upgrade OpenSSL
without recompiling systemd.

To fix this, drop the ENGINE API symbols from the mandatory DLSYM_ARG() list.
Instead, try to load them via DLSYM_OPTIONAL() after the library is opened.
load_key_from_engine() is updated to check for their presence and return
-EOPNOTSUPP if the loaded OpenSSL version does not provide them.
2026-07-03 03:02:56 +09:00
Yu Watanabe 3aaffa43f0 crypto-util: drop dlopen_libcrypto() from static functions 2026-07-03 03:02:56 +09:00
Yu Watanabe 75bc106095 memory-util: drop unused memdup_reverse()
With the previous commit, now the function is unused anymore.
Let's drop it.
2026-07-03 03:02:56 +09:00
Yu Watanabe b5e75134f3 crypto-util: drop manual endianness handling in rsa_pkey_from_n_e()
Currently, rsa_pkey_from_n_e() uses architecture-specific `#if` branches
and memdup_reverse() to handle big-endian RSA components (n and e)
before passing them directly to OSSL_PARAM_construct_BN().

We can simplify this by parsing the raw big-endian bytes into BIGNUMs
first using BN_bin2bn(), which natively expects big-endian data. We
can then push these BIGNUMs into OSSL_PARAM_BLD. This delegates the
data format handling entirely to OpenSSL and successfully removes the
platform-specific code.
2026-07-03 03:02:56 +09:00
Yu Watanabe fc54be2f66 crypto-util: simplify openssl_extract_public_key()
Drop memstream and i2d_PUBKEY_fp(). We can simply use i2d_PUBKEY()
which automatically allocates the necessary buffer for us.

Note that dropping the secure erase (erase_and_freep()) in favor of
OPENSSL_free() is intentional and safe, as the buffer only holds
public key material which does not need to be securely wiped.
2026-07-03 03:02:56 +09:00
Yu Watanabe 94e8d7209e crypto-util: use correct cleanup function for OpenSSL buffers
Buffers allocated by OpenSSL must be freed with OPENSSL_free().
Fortunately, we do not enable the secure heap, so OPENSSL_free()
is currently equivalent to free(), but let's fix this for correctness.
2026-07-03 03:02:56 +09:00
Yu Watanabe c0c6a9e8e4 crypto-util: simplify pubkey_fingerprint()
There is no need to call i2d_PublicKey() twice. Passing a pointer
to NULL allows OpenSSL to automatically allocate the necessary buffer.
2026-07-03 03:02:56 +09:00
Yu Watanabe ec35f207b6 crypto-util: drop unused deprecated symbols 2026-07-03 03:02:56 +09:00
Yu Watanabe c18ee628a5 resolved: migrate ECDSA verification to OpenSSL 3 EVP API
OpenSSL 3.0 deprecated low-level Elliptic Curve (EC) key manipulation
functions (EC_KEY, EC_POINT, EC_GROUP) and direct signature verification
functions like ECDSA_do_verify().

This commit modernizes dnssec_ecdsa_verify_raw() by transitioning to the
provider-aware EVP API:
* Uses OSSL_PARAM arrays and EVP_PKEY_fromdata() to construct the EC
  public key directly from the raw octet string and curve name, avoiding
  deprecated EC_POINT parsing.
* Converts the raw R and S signature components into a DER-encoded ASN.1
  signature using i2d_ECDSA_SIG(), as required by the modern EVP API.
* Uses EVP_PKEY_verify() for the actual signature validation.

Additionally, this drops an outdated TODO comment waiting for raw ECDSA
support in the EVP API, as well as the deprecated warning suppression
macros and fallback code blocks. Unit tests for ECDSA are now run
unconditionally.
2026-07-03 03:02:56 +09:00
Yu Watanabe 13be553507 resolve: make dnssec_ecdsa_verify_raw() take struct iovec
This also
- adds missing assertions,
- moves variable declarations,
- rename variables.

No functional change, just refactoring.
2026-07-03 03:02:56 +09:00
Yu Watanabe 59fa4dd142 resolve: add unit test for dnssec_ecdsa_verify_raw() 2026-07-03 03:02:56 +09:00
Yu Watanabe cd3c0859b2 resolved: migrate RSA key construction to OpenSSL 3 EVP API
OpenSSL 3.0 deprecated low-level key manipulation functions and direct
access to RSA structures (such as RSA_new(), RSA_set0_key(), and
RSA_size()).

This commit modernizes dnssec_rsa_verify_raw() by replacing these
deprecated functions with the provider-aware EVP API:
* Uses OSSL_PARAM_BLD and EVP_PKEY_fromdata() to construct the RSA
  public key directly from the modulus and exponent BIGNUMs.
* Replaces RSA_size() with EVP_PKEY_get_size().

Consequently, the workaround macros suppressing deprecated warnings
(DISABLE_WARNING_DEPRECATED_DECLARATIONS) and the conditional fallback
blocks (#if !defined(OPENSSL_NO_DEPRECATED_3_0)) are no longer needed
and have been dropped. Unit tests are also updated to run unconditionally.
2026-07-03 03:02:56 +09:00
Yu Watanabe 918193b438 resolve: make dnssec_rsa_verify_raw() take struct iovec
This also
- adds missing assertions,
- moves variable declarations.

No functional change, just refactoring.
2026-07-03 03:02:56 +09:00
Yu Watanabe 6bf0540e93 resolve: add unit test for dnssec_rsa_verify_raw() 2026-07-03 03:02:56 +09:00
Yu Watanabe 5fec7096cf crypto-util: load several more symbols
They will be used in later commits.

Note, ECDSA_SIG_new() and ECDSA_SIG_set0() are not deprecated.
They are moved to the section for non-deprecated symbols.
2026-07-03 03:02:56 +09:00
Yu Watanabe 6268b094eb resolve: fix segfault when built with OPENSSL_NO_DEPRECATED_3_0
In that case, deprecated funcdions are not loaded from libcrypto.so,
and calling them causes segfault.
2026-07-03 03:02:56 +09:00
dongshengyuan bd1bb49ffa coredumpctl: use break instead of continue for time bound checks
When iterating journal entries with --until (forward scan) or --since
(reverse scan), the code used continue instead of break after crossing
the time boundary.

Since sd_journal_seek_realtime_usec() is called before the loop to
position at the start of the range, sd_journal_next()/previous()
returns entries in monotonically increasing/decreasing time order.
Once an entry's timestamp exceeds arg_until (or falls below arg_since
in reverse), all subsequent entries will also be out of range.

Using continue caused the entire remaining journal to be scanned
unnecessarily. journalctl uses break for the identical pattern in
src/journal/journalctl-show.c.

Fixes: #42808
Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
2026-07-02 18:46:39 +02:00
Tim Schumacher e0ec80d63c udev: Tag debug appliance nodes as xaccess-debug-appliance
This is especially helpful for people who are running headless (i.e.
SSH-only) Android platform development setups with testing devices
attached.
2026-07-02 18:14:21 +02:00
Luca Boccassi 964f0607e4 man: add thread-awareness note to sd_bus/sd_event manpages
This question comes up every now and then, and it is not clearly documented,
so include the thread-aware tag in all bus/event manpages.
2026-07-02 17:04:07 +01:00
Luca Boccassi 243fcc6200 man: note that sd-tmpfiles/sysusers --root is not a sandboxing feature
This seems to be causing enough confusion that it is worth explicitly
mentioning in the docs
2026-07-02 17:02:40 +01:00
Kai Lüke ff30101e81 vmspawn/nspawn: Always use a per-machine runtime subdirectory
Some state files were prefixed with the machine name which protected
against collisions when running concurrent machines in a systemd unit
with RuntimeDirectory= set. However, the socket files tpm.sock and
control were not, which caused a race. Prefixing these socket files
does not work because the path gets too long when both the subdirectory
and the socket file within it get unique identifiers.

Instead of prefixing all files, we can rather always create a
subdirectory and use simple names within in. This makes paths shorter
in the normal case and protects against races with RuntimeDirectory=
were instead of directly reusing RUNTIME_DIRECTORY we also create the
normal per-machine subdirectory. Since this here is about runtime state
it should not impact any running VMs/containers. The ssh-proxy looks
only at the normal case and does not support RUNTIME_DIRECTORY, so no
impact there as well.
2026-07-02 17:24:18 +02:00
Daan De Meyer d08882653d meson: fix fs.exists() check for fuzz corpus samples
Commit 8355eb6e11 ("meson: Check if files returned by git ls-files
actually exist") checks the paths printed by git ls-files, which are
relative to the project root, with fs.exists(), which resolves them
relative to the test/fuzz subdirectory. As a result, every corpus
sample was silently skipped, and only the generated directives tests
were registered. Resolve the paths against the project source root
instead.
2026-07-02 15:33:28 +01:00
Daan De Meyer 62c5c888f4 compress: handle ZSTD_CONTENTSIZE_UNKNOWN when decompressing blobs
The zstd blob decompression code assumed ZSTD_getFrameContentSize() always
returns the decompressed size, which holds for the journal and coredump blobs
systemd compresses itself with the one-shot ZSTD_compress(). Frames produced by
the streaming API, however, don't record the decompressed size in their header,
so ZSTD_getFrameContentSize() returns ZSTD_CONTENTSIZE_UNKNOWN. Per the zstd
documentation this is not an error, but decompress_blob_zstd() and
decompress_startswith_zstd() bailed out with -EBADMSG regardless.

This broke kexec of kernel images compressed with 'zstd' (e.g. zstd -22), whose
ZBOOT payload is decompressed via decompress_blob().

Treat only ZSTD_CONTENTSIZE_ERROR as fatal and, when the size is unknown, grow
the output buffer as we stream the frame out instead of relying on the recorded
size. Add a regression test that feeds a streaming-compressed (hence
unknown-size) zstd frame through decompress_blob() and decompress_startswith().
2026-07-02 16:09:26 +02:00
Philip Withnall 075f74a19c docs: Update memory pressure docs for latest GLib support for it
As of GLib 2.90.0 (not yet released), GLib will fully support the spec,
including the `MEMORY_PRESSURE_WATCH` and `MEMORY_PRESSURE_WRITE`
environment variables, which it did not support previously.

See https://gitlab.gnome.org/GNOME/glib/-/merge_requests/5046
2026-07-02 15:05:14 +01:00
Frantisek Sumsal 60d982d3fc test: suppress fails on the Africa/Tripoli (Libya) timezone
As it switched between CET and EET multiple times in the past, causing
random fails with certain historical timestamps:

834/1524 test - systemd:test-time-util     FAIL    0.96s   killed by signal 6 SIGABRT
 ...
TZ=Africa/Tripoli, tzname[0]=EET, tzname[1]=CEST
@378687574661411 → Thu 1981-12-31 23:59:34 CET → @378683974000000 → Thu 1981-12-31 23:59:34 EET
src/test/test-time-util.c:450: Assertion failed: Expected "ignore" to be true
/builddir/build/BUILD/systemd-261.1-build/systemd-261.1/tools/test-crash-trace.sh: line 18: 87088 Aborted                    (core dumped) "$@"
2026-07-02 13:17:06 +01:00
Paul Meyer 1ef7c15bd8 ukify: show all sections and profiles in inspect JSON output
The JSON output keyed every section by name, so a UKI with repeated
sections only showed the last one: in a multi-profile UKI all but one
.profile/.cmdline/.pcrsig were dropped, as were extra .dtbauto/.efifw.

Report the shared base sections by name at the top level (so .cmdline
etc. stay where they were), each profile as its own by-name object under
a new "_profiles" array, and the alternative-set sections (.dtbauto,
.efifw) as arrays.

Co-developed-by: Claude Opus 4.8 <noreply@anthropic.com>
Signed-off-by: Paul Meyer <katexochen0@gmail.com>
2026-07-02 13:26:33 +02:00
Paul Meyer 6603180b38 boot: measure SMBIOS via non-TPM runtime measurements
In commit 29c6d1c125 ("boot: measure select SMBIOS objects
explicitly") we added an explicit SMBIOS measurement in systemd-boot
and systemd-stub, covering cases where firmware doesn't measure SMBIOS
itself. measure_smbios() bailed unless a TPM was present, so it skipped
the measurement on confidential guests that only expose a CC
measurement protocol (e.g. Intel TDX RTMRs).

We can have much higher expectations of the virtual firmware used for
confidential computing, and the firmware is attested, so we can expect
it to always measure SMBIOS in this case. We still do our own
measurement to get a measurement structure similar to that of
non-confidential guests, and as another line of defense.

Signed-off-by: Paul Meyer <katexochen0@gmail.com>
2026-07-02 11:43:13 +01:00
Paul Meyer 34f0384c53 shell-completion: add tdx to systemd-vmspawn --coco values
Missed in a78afc1616 ("vmspawn: add Intel TDX confidential VM
support")

Signed-off-by: Paul Meyer <katexochen0@gmail.com>
2026-07-02 10:55:39 +01:00
Luca Boccassi dbcf482492 terminal-util: tweaks for show_menu() (#42822) 2026-07-02 10:02:53 +01:00
Michael Vogt 896fd702ba firstboot: add new systemd.firstboot=headless mode
This adds a new systemd.firstboot=headless mode. It differs from the
existing systemd.firstboot=no mode in that it still performs the
non-interactive auto-configuration that requires no user input (such
as selecting the only installed locale, or applying settings provided
via credentials), and only skips the prompts that would otherwise
block waiting for user input. In contrast, =no disables that
auto-configuration along with the prompts.

The option is also honoured by homectls firstboot logic and
systemd-cryptenroll, where headless behaves the same as no
(because the is no auto-configuration).
2026-07-02 09:52:21 +01:00
Lennart Poettering bd13921c78 test: add test case for show_menu() 2026-07-02 08:20:59 +02:00
Lennart Poettering 00af6e918b terminal-util: drop assert() on 'x'
We happily take a NULL strv as argument, equivalent to an empty one,
like most of our strv handling funcs.
2026-07-02 08:20:59 +02:00
Lennart Poettering a0b6644796 terminal-util: make sure we never go below 10 characters line width 2026-07-02 08:20:59 +02:00
Lennart Poettering 6e9a1c4cd6 terminal-util: use LESS_BY() where appropriate 2026-07-02 08:18:36 +02:00
Lennart Poettering 72c6ac77e3 terminal-util: calculate array index only once 2026-07-02 08:18:36 +02:00
Luca Boccassi 03b498d8a8 core: assorted hardening fixes flagged by kres (#42840) 2026-07-02 00:57:06 +01:00
Luca Boccassi f738dcb3b7 bpf-restrict-fs: use a 32-bit magic key on big-endian too
The inner map is created with a uint32_t key, but the update passed
&magic[i] where magic is a (possibly 64-bit) statfs_f_type_t. On
little-endian the low 32 bits happen to be read; on big-endian 64-bit
(s390x, ppc64 BE) the zero high word is read instead, so every
filesystem collides on key 0 (the allow/deny selector) and
RestrictFileSystems= is silently broken. Pass a truncated copy.

Follow-up for 184b4f78cf
2026-07-01 22:46:45 +01:00
Luca Boccassi 62c182f0d5 core/scope: don't assert when start is retried during cgroup chown
While a delegated scope waits for the async cgroup chown helper it sits
in SCOPE_START_CHOWN (UNIT_ACTIVATING). unit_start() forwards to
->start() while activating, so scope_start() could be re-entered in
that state and trip assert(s->state == SCOPE_DEAD), aborting PID 1.
Treat SCOPE_START_CHOWN as already-starting instead.

Follow-up for 03860190fe
2026-07-01 22:46:45 +01:00
Luca Boccassi b64a44707d core: donate the fdset to do_reexecute() to avoid a double free
do_reexecute() freed the FDSet on the switch-root/soft-reboot fallback
but the caller's copy stayed live, so main() freed it again if every
fallback exec then failed. Donate the fdset instead: pass it with
TAKE_PTR() and take ownership via a _cleanup_ local, freeing it exactly
once on every exit path.

Follow-up for 3c7878f94b
2026-07-01 22:46:45 +01:00
Shihao Ren 48dc1bbd09 run: refuse --no-block when combined with --scope
In the systemd-run --scope mode, --no-block has no actual effect and will
be silently ignored. Therefore, this combination is explicitly rejected to
reduce confusion for users when using it.

Fixes: #42806
2026-07-01 23:37:44 +02:00
Lennart Poettering afcc11d938 crypto-util, ssl-util: set log level to debug in dlopen_many_sym_or_warn() (#42811)
Otherwise in systems with OpenSSL 3 the journal contains multiple error
entries because the preferred library libcrypto.so.4 is not present.

Follow-up for ccdd42351f
2026-07-01 22:15:51 +02:00
Lennart Poettering 62db9abc38 vmspawn: add Intel TDX confidential VM support (#42835) 2026-07-01 22:14:09 +02:00
Lennart Poettering 66f7a14c6d mkfs-util: fixes for mtools invocation (#42839) 2026-07-01 22:10:49 +02:00
Luca Boccassi a96c0075d4 tree-wide: trivial sysconf() invocations tweaks (#42837) 2026-07-01 19:42:52 +01:00
Luca Boccassi 0a869d3882 shared/install: give the borrowed name back before bailing on error
In the unmask path, when install_changes_add() fails the borrowed
*name was not handed back via TAKE_PTR() before returning, so
install_info_clear() freed the caller's strv entry, leaving a dangling
pointer that is double-freed at the caller's strv_free().

Follow-up for f31f10a620
2026-07-01 18:18:00 +01:00
Luca Boccassi 61196f5817 quotacheck: don't apply an invalid quotacheck.mode= value
quota_check_mode_from_string() returns -EINVAL on a bad value, storing
it in the global arg_mode. Only change arg_mode on success.

Follow-up for d73691c64e
Follow-up for dba4fe9a60
2026-07-01 18:18:00 +01:00