Commit Graph
7789 Commits
Author SHA1 Message Date
Michal Sekletar c5b508b0c7 socket-util: fix socket_xattr_supported() in initramfs
Don't test xattr support on socket created in filesystem. This doesn't
work in initramfs when /tmp doesn't have tmpfs mounted inside as
initramfs doesn't have xattr support. Setting socket xattr falls back to
parent directory xattr handlers when we work with FS based socket.

Let's test sockfs based socket instead so that the check is generic and
works in all environments.
2026-07-08 17:54:27 +01:00
Frantisek Sumsal 9ae50c78cc sd-event: use CLOCK_BOOTTIME for rate limits
When a rate limit is armed, for example via StartLimitInterval=, and the
machine is suspended, the rate limit's "clock" is suspended as well,
since the elapse checks use CLOCK_MONOTONIC. This then causes unexpected
situations where a rate limit armed via StartLimitInterval=1h, followed
by a 10 hour suspend, would elapse after 11 hours total.

Let's avoid this by switching the rate limits to CLOCK_BOOTTIME, which
works the same as CLOCK_MONOTONIC, but accounts for the time spent in
suspend as well.

There's one slight concern when it comes to upgrade path - the old
"begin" value of the rate limit is stored as CLOCK_MONOTONIC, but after
upgrading systemd and serializing/deserializing the state it will be
suddenly compared against now(CLOCK_BOOTTIME), which might cause some
rate limits to elapse "prematurely". But this is just a one-time thing,
after which the rate limit timers should re-assess themselves.

Resolves: #42912
2026-07-08 15:38:39 +01:00
Luca Boccassi 87e57c52c1 hashmap: honor the value destructor in set_ensure_consume()
Sets store their element in the key slot but use a value destructor
(DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR). On the reject/duplicate path
set_ensure_consume() only checked free_key and otherwise called free().

Follow-up for fcc1d0315d
2026-07-06 13:42:21 +01:00
Yu Watanabe 5280cd7bdb tree-wide: check if necessary cflags dependencies are set
This makes each `foo_cflags` dependency define a `SYSTEMD_CFLAGS_MARKER_FOO`
macro, and checks if the macro is set when headers provided by external
libraries are included.

With this, we can fail fast at compile time if necessary `_cflags`
dependencies are omitted in meson.build. Missing dependencies found by this
mechanism have been added across the tree.
2026-07-03 21:50:45 +09:00
dongshengyuan 21de611f69 calendarspec: warn on weekday/date conflict in systemd-analyze and systemd-run
When a fixed date (e.g. 2027-01-01) is paired with a weekday constraint
(e.g. Thu) that does not match, the timer silently never elapses.

Add calendar_spec_from_string_full(..., warn_on_weekday_mismatch) so
user-facing tools can opt in to a log_warning() at parse time:
- systemd-analyze calendar: uses _full(true)
- systemd-run --on-calendar: uses _full(true)
- .timer OnCalendar=: uses log_syntax() with file/line context

Add test_calendar_spec_weekday_conflict(): forks a child with stderr
captured in a memfd via pidref_safe_fork_full(), verifies the warning
is emitted for conflicting specs and suppressed for valid ones.

Fixes: #40350
Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
2026-07-03 07:39:49 +02:00
Yu Watanabe 2d372e2a34 Improve OpenSSL 4 support (#42843) 2026-07-03 07:20:48 +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
Zbigniew Jędrzejewski-Szmek 83e4074af1 manager: use reboot.target as the default for ctrl-alt-del.target
systemd tries to start ctrl-alt-del.target after receiving a request
to reboot in a container (or when ctrl-alt-del is pressed on a real
machine). If the alias is missing, this will fail. Let's provide a
fallback for this too. I don't think it makes sense to make it
configurable: it seems almost everybody is fine with the default
mapping. If not, people can always just create the symlink in the
filesystem.
2026-07-02 17:19:18 +02:00
Zbigniew Jędrzejewski-Szmek 5c2bd19f40 user-util: add getgrouplist_malloc and initgroups_wrapper 2026-07-02 17:19:18 +02:00
Zbigniew Jędrzejewski-Szmek bbeef4b948 various: add -Dbuild-static and alternatives to libc functions
When we try to build with -static, the linker refuses dlopen and
various functions related to nss. This commit adds the basic support
to compile with -static and allow the link to pass.
2026-07-02 17:19:18 +02:00
Zbigniew Jędrzejewski-Szmek b3749de21c user-util: add lookup_groups_in_files 2026-07-02 17:19:18 +02:00
Zbigniew Jędrzejewski-Szmek 2c01b4895e user-util: sysconf_ngroups_max
This hides the iffy interface of sysconf(_SC_NGROUPS_MAX) to simplify
the calllers.
2026-07-02 17:19:18 +02:00
Zbigniew Jędrzejewski-Szmek aac88fd8ab user-util: add lookup_pwent_in_files and lookup_grent_in_files
Those functions will be used later. This commits adds the
implementations and tests for them.

glibc functions require ability to open nss modules, which requires
dlopen. Linking will fail if any of the nss-using functions are used.
So the following few commits will provide replacements for all of
them.
2026-07-02 17:19:18 +02: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
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
Lennart Poettering 818b3b31e6 time-util: use sysconf_clock_ticks_cached() at all places we query _SC_CLK_TCK 2026-07-01 16:14:19 +02:00
Lennart Poettering 60bac209eb memory-util: don't use 'r' for non-int returns 2026-07-01 16:14:19 +02:00
Lennart Poettering d769892ad0 env-util: use our own sc_arg_max() helper at more places 2026-07-01 16:14:19 +02:00
Luca Boccassi 1958539136 env-util: ensure NUL termination of the replace_env_argv() output array
The output array is allocated with new() and left uninitialized, but a
bare unset "$VAR" token expands to nothing and writes no terminator.
When such a token leads or is the only word, the returned strv is left
without a trailing NULL.

Follow-up for f331434d13
2026-06-30 11:49:53 +01:00
Yu Watanabe 25714364a9 locale-util: drop libintl dependency
Both glibc and musl provides dgettext(). Hence it is not necessary to
use libintl.so provided by gettext.

This partially reverts 590e226437,
fully reverts commit e6e65dc261 and
bd19ffd9cb.

Then, introduce minimal libintl.h for musl build, to avoid using
libintl.h by gettext, which is typically installed on musl-based
build systems.
2026-06-29 23:22:41 +09:00
Jouke Witteveen 5a03efc9c1 Correct allocation size computation in xescape_full
Amends 17260a9 (#42524).

Since there is no return path with an incomplete write, the effect of
the memset block was unobservable, so drop it.
2026-06-28 12:52:47 +09:00
Yu Watanabe 6461c1b017 tree-wide: drop gcrypt dependency from all binaries except for unit tests
With this change, gcrypt dependency is not mandatory. Hence, allow to build
systemd even when -D gcrypt=enabled but gcrypt devel package is not installed.
2026-06-28 00:26:56 +09:00
Yu Watanabe 24c4729198 sd-journal: drop libgcrypt dependency from libsystemd
This introduce a vtable for journal tagging feature in sd-journal,
and makes libgcrypt dependent features loaded by users (journald,
journalctl, journal-remote, and unit tests) when necessary.
2026-06-28 00:00:11 +09:00
Yu Watanabe 82ff3f71f5 iovec-util: introduce several helper functions 2026-06-27 14:04:48 +09:00
Lennart Poettering 4162b65338 unit-name: introduce "strict" mode for unit name mangling (#42638)
unit_name_mangle_with_suffix() is quite benevolent by default and allows
the unit to "transition" into a different unit type than what's
requested via its suffix argument. For example, calling
unit_name_mangle_with_suffix() with "/foo/bar" as a unit name and
".service" as a suffix would give you "foo-bar.mount", without any
warning or error.

This could then lead to a quite confusing errors in certain situations:
```
~# systemd-run --remain-after-exit --unit /foo/bar true
Failed to start transient service unit: Cannot set property RemainAfterExit, or unknown property.
```
Given we can't change the default behaviour of
unit_name_mangle_with_suffix() as some parts of systemd already depend
on its "benevolence" (like systemctl), let's introduce a new flag -
UNIT_NAME_MANGLE_STRICT - that checks if the mangled/resolved unit
name's suffix matches the requested one and errors out if not.

With the flag used throughout systemd-run's code, the error in the above
case is now a bit more clear:
```
~# build/systemd-run --remain-after-exit --unit /foo/bar true
Path "/foo/bar" resolves to unit type "mount", but "service" is expected as unit.
Failed to mangle unit name: Invalid argument
```
Resolves: #39996
2026-06-25 17:18:55 +02:00
Lennart Poettering 16e96b03b1 tpm2: add SWTPM fallback test, fixes and hardening (#42722) 2026-06-25 17:13:03 +02:00
Zbigniew Jędrzejewski-Szmek 3498b84013 Couple of hardening changes for utils flagged by kres (#42732) 2026-06-25 14:31:35 +02:00
Paul Meyer 47b6a20621 fileio: add write_string_filef_at()
Signed-off-by: Paul Meyer <katexochen0@gmail.com>
2026-06-25 13:33:22 +02:00
Frantisek Sumsal 14b1a92eb2 unit-name: introduce "strict" mode for unit name mangling
unit_name_mangle_with_suffix() is quite benevolent by default and allows
the unit to "transition" into a different unit type than what's
requested via its suffix argument. For example, calling
unit_name_mangle_with_suffix() with "/foo/bar" as a unit name and
".service" as a suffix would give you "foo-bar.mount", without any
warning or error.

This could then lead to a quite confusing errors in certain situations:

~# systemd-run --remain-after-exit --unit /foo/bar true
Failed to start transient service unit: Cannot set property RemainAfterExit, or unknown property.

Given we can't change the default behaviour of
unit_name_mangle_with_suffix() as some parts of systemd already depend
on its "benevolence" (like systemctl), let's introduce a new flag -
UNIT_NAME_MANGLE_STRICT - that checks if the mangled/resolved unit
name's suffix matches the requested one and errors out if not.

With the flag used throughout systemd-run's code, the error in the above
case is now a bit more clear:

~# build/systemd-run --remain-after-exit --unit /foo/bar true
Path "/foo/bar" resolves to unit type "mount", but "service" is expected as unit.
Failed to mangle unit name: Invalid argument

Resolves: #39996
2026-06-25 12:58:06 +02:00
Frantisek Sumsal 89f1f76624 unit-name: use FLAGS_SET() more 2026-06-25 11:31:28 +02:00
Luca BoccassiandPaul Meyer d30e87ea49 uid-range: fix out-of-bounds write in uid_range_partition()
uid_range_partition() filled the grown entries[] buffer backwards in
place. The backward-fill invariant (the write cursor stays above the
read index) only holds when every source entry contributes at least
one partition; an entry with nr < size contributes zero, so the cursor
stalls while the read index keeps descending. A later multi-part
entry's writes then overwrite the still-live zero-part slot, the
corrupted slot is re-read as a one-part entry, and the next
range->entries[--t] underflows.

Add a forward compaction first pass that drops the zero-part entries
before the backward fill.

Follow-up for 025439faaa

Co-Authored-by: Paul Meyer <katexochen0@gmail.com>
2026-06-25 10:28:54 +01:00
Michael Vogt bc4dfc24a5 basic: add assert() when doing pointer deref
Lennart reminded me in [1] that we need to add assert() in functions
that do pointer access. For the simple `*p` pointer dereferences
we even have an automatic coccinelle script that ensures that as
part of the automatic code checks.

However for deref in the `p->` style this is not supported right
now and adding it to coccinelle is hard because its too slow for
this kind of check. So I created a (slightly messy) tree-sitter
python script to see how many asserts we are currently missing.

This commit is the result of running it over the `src/basic`
dir and fixing the flagged issues. I plan to tidy it up and
add it to the checks too but this is orthogonal to this commit.

[1] https://github.com/systemd/systemd/pull/42360#discussion_r3426964562
2026-06-25 10:40:21 +02:00
Luca Boccassi f66144cf2a string-util: check for short input in previous_ansi_sequence()
ellipsize_mem() scans backwards for ANSI escape sequences and calls
previous_ansi_sequence(s, t - s, ...) as t walks down toward s. When
t reaches s + 1 the helper is invoked with length == 1 and computes
'length - 2', which wraps to SIZE_MAX - 1.

Follow-up for cb558ab222
2026-06-24 14:48:04 +01:00
Lennart Poettering d36bdc9467 sysupdate: notify hook subscribers after a successful update
Define a new io.systemd.SysUpdate.Notify Varlink interface with a single
OnCompletedUpdate() method, and after sysupdate successfully installs an
update, invoke that method on every socket linked into
/run/systemd/sysupdate/notify/ via varlink_execute_directory(). This
gives other components a hook to react to applied updates (e.g. recompute
a TPM policy, link a freshly downloaded kernel, refresh extensions).

The notification carries the component name, the installed version and the
list of updated resources (transfer id + on-disk path). Subscribers are
free to ignore the parameters and just treat the call as a trigger.

Setting SYSTEMD_SYSUPDATE_FORCE_NOTIFY=1 forces the notification to be sent
even when no update was applied (in which case no resource list is included),
so follow-up work can be triggered unconditionally.

Fixes: #35988
2026-06-24 13:05:33 +02:00
Lennart Poettering daae289f10 sd-netlink: beef up sock-diag code a bit
Let's make it useful to enumerate AF_UNIX sockets.
2026-06-23 23:10:01 +02:00
Lennart Poettering ce72c94acc bpf-restrict-fsaccess: move STAT_DEV_TO_KERNEL into generic code
We want to reuse it when processing sock-diag messages, hence let's
generalize this.
2026-06-23 22:55:23 +02:00
Lennart Poettering f304250315 socket-util: add new helper socket_xattr_supported() 2026-06-23 22:55:23 +02:00
Lennart Poettering e1bdd512ed xattr-util: use empty_to_null() where appropriate 2026-06-23 22:55:23 +02:00
Paul Meyer fb1bdb9eff confidential-virt: read the TDX CPUID leaf unconditionally
detect_tdx() guarded the read of the TDX enumeration leaf (0x21, a
standard leaf) with CPUID_GET_HIGHEST_FUNCTION (0x80000000), which
returns the highest *extended* function. eax is therefore always
>= 0x80000000, so the "eax < 0x21" guard never held and the leaf was
read unconditionally anyway.

Drop the guard rather than re-gate it on the basic max function
(leaf 0), and read 0x21 directly, relying on the IntelTDX signature
compare. This matches the kernel, which reads the leaf unconditionally
on purpose: an out-of-range CPUID leaf returns the highest basic leaf's
data (no fault, per the Intel SDM), and 0x21 is a synthetic TDX leaf
whose presence need not be reflected in the reported max basic function,
so gating the read on it risks missing a genuine TDX guest. With no
guard the Hyper-V isolation fallback (Azure TDX guests have 0x21
blocked) also stays reachable.

Ref: Linux 59bd54a84d15 ("x86/tdx: Detect running as a TDX guest in
early boot"), arch/x86/coco/tdx/tdx.c:1119 (tdx_early_init()).

Signed-off-by: Paul Meyer <katexochen0@gmail.com>
2026-06-23 12:35:54 +02:00
Paul Meyer d76ce200a6 confidential-virt: treat an unreadable SEV MSR as confidential
msr() returned 0 on failure, indistinguishable from a real MSR value of
0. With /dev/cpu/0/msr unavailable (e.g. the msr module not loaded in the
initrd), detect_sev() read 0 and reported a genuine SEV/-ES/-SNP guest as
CONFIDENTIAL_VIRTUALIZATION_NONE.

That inverts the firmware-credential trust gate: import_credentials_*()
skip fw_cfg/SMBIOS credentials only when detect_confidential_virtualization()
is > 0 ("don't trust firmware in confidential VMs"). A false NONE makes a
confidential guest trust and import credentials injected by the untrusted
hypervisor.

msr() now returns a negative errno, and detect_sev() assumes plain SEV when
the MSR is unreadable but CPUID already advertised SEV under a hypervisor,
so the gate still trips.

The conservative branch only fires when CPUID already advertised SEV, i.e.
for a guest the hypervisor marked SEV-capable. QEMU gates that CPUID leaf on
the SEV launch object and does not expose it to ordinary guests even under
-cpu host, so it does not misfire for non-confidential guests. Were a
hypervisor to expose the bit anyway the outcome is fail-safe (we only
decline to trust firmware-supplied data); nothing in-tree branches on the
specific SEV tier.

Signed-off-by: Paul Meyer <katexochen0@gmail.com>
2026-06-23 11:55:00 +02:00
Gabriel 983f8610b7 Add handling for '-1' when parsing vsock CID (#42654)
Currently `systemd-ssh-generator` supports
`systemd.ssh_listen=vsock::22` and aliases the "empty CID" towards
`VMADDR_CID_ANY`. VMADDR_CID_ANY is -1, so it's confusing from a user
experience that `systemd.ssh_listen=vsock:-1:22` isn't supported.
2026-06-22 21:57:03 +02:00
Lennart Poettering 710d5aebbb sysupdate: keep database of installed files/patterns, and use to GC them (#42646)
Transfer files might come and go, components might be enabled and
disabled. Patterns might change. Let's keep track of what we install, so
that we can automatically gc everything no longer owned by any enabled
transfer.
2026-06-22 17:19:46 +02:00
Luca Boccassi 4dc1e31ce8 machine-tags: extend syntax to support key/value pairs (#42618)
This is a minor extension, to move the machine tags concept more closely
towards what higher-level solutions support for tagging machines, such
as kubernetes, simply to reduce the conceptual impedance mismatch.
2026-06-22 14:47:20 +01:00
Lennart Poettering dbd35fdc81 string-util: introduce STRING_FILENAME_PART flag for string_is_safe()
Whenever we are validating a string that shall appear in a filename
eventually we want to use filename_part_is_valid() rather than file
filename_is_valid(). Let's add explicit support for that to
string_is_safe(), since it's actually a really common case.
2026-06-22 14:41:16 +02:00
Lennart Poettering 90d285ade7 recurse-dir: optionally, only enumerate dentries of a specific type
At various places we filter directory enumerations by inode type. Let's
add explicit support for that, so that the "struct dirent" array we
return already suppresses them.

This shortens code and makes things more robust.
2026-06-22 14:40:16 +02:00
Lennart Poettering fe83c5be7f sha256: add sha256_direct_hex() helper
A various places we need a SHA256SUM of something as a string. Let's add
a simple helper for this that does this generically.
2026-06-22 14:39:50 +02:00
Luca Boccassi a8e5746ef3 log: add log_struct_once macro
Combines log_once and log_struct
2026-06-22 10:54:49 +01:00