Commit Graph
87946 Commits
Author SHA1 Message Date
Nick Rosbrook da18a5cfd6 test: do not use nanoseconds width specifier in date command
Using the format specifier +%s%6N with GNU date is honored, and only
prints 6 digits of the nanoseconds portion of the seconds since epoch.
The uutils implementation of date does not honor this, and always prints
all 9 digits. This is a known bug[1], but can be worked around by
adapting this test to use nanoseconds instead of microseconds.

[1] https://github.com/uutils/coreutils/issues/11658
2026-04-14 14:54:32 +01:00
Daan De Meyer 78ab4d1f7d parse-helpers: Silence coverity warning 2026-04-14 15:51:02 +02:00
Lennart Poettering 03ee08d1d7 tree-wide: convert remaining varlink string fields to enum types (#41615)
Follow-up to #40972. Convert remaining plain string fields to proper
varlink enum types across all interfaces, per the policy that
user-controlled/API fields should be declared as proper enums in the
IDL.

Interfaces converted:
- io.systemd.Manager — LogTarget, DefaultStandardOutput/Error,
DefaultMemory/CPU/IOPressureWatch, DefaultOOMPolicy,
CtrlAltDelBurstAction (8 fields)
- io.systemd.Unit — CPUSchedulingPolicy, IOSchedulingClass, NUMAPolicy,
MountFlags (4 fields)
- io.systemd.Machine — class, whom (2 fields, input dispatch converted
to JSON_DISPATCH_ENUM_DEFINE for automatic dashify fallback)
- io.systemd.oom / io.systemd.ManagedOOM — mode in ControlGroup (1
field)

Shared types moved to varlink-idl-common: ExecOutputType,
CGroupPressureWatch, EmergencyAction, ManagedOOMMode — these are reused
across multiple interfaces.

Each interface change includes a corresponding enum sync test to catch
future drift between C string tables and varlink IDL definitions.
2026-04-14 14:04:13 +02:00
Lennart Poettering 1b53324959 tree-wide: use JSON_BUILD_PAIR_ENUM() more often 2026-04-14 13:58:36 +02:00
Ivan Kruglov 3dd09ccea2 docs: clarify when to use varlink enum types vs plain strings
Add guidance on when a field should use a proper varlink enum type
versus remaining a plain string: user-controlled/API fields should be
enums, engine-internal state fields may stay as strings.

Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-14 13:37:02 +02:00
Ivan Kruglov 6518bcf872 varlink: add ManagedOOMMode enum type to io.systemd.oom
Convert the mode field in ControlGroup from plain string to the
ManagedOOMMode enum type from varlink-idl-common. Register
ManagedOOMMode in both io.systemd.oom and io.systemd.ManagedOOM
interfaces since both use the ControlGroup struct.

Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-14 02:10:52 -07:00
Ivan Kruglov 5d0ac2c23c varlink: add enum types for class and whom fields in io.systemd.Machine
Convert the class field (Register input, List output) from plain string
to MachineClass enum type, and the whom field (Kill input) to KillWhom
enum type.

Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-14 02:10:52 -07:00
Ivan Kruglov 2fda0fb4c7 varlink: add enum types for scheduling and mount settings in io.systemd.Unit
Convert CPUSchedulingPolicy, IOSchedulingClass, NUMAPolicy and MountFlags
fields from plain strings to proper varlink enum types in the io.systemd.Unit
interface. Update the corresponding serialization code to use
json_underscorify() for correct enum value formatting.

Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-14 02:10:52 -07:00
Ivan Kruglov b5aa7635ce varlink: add enum types for configuration settings in io.systemd.Manager
Convert 8 string fields in the io.systemd.Manager varlink interface to
proper enum types:

- LogTarget: new enum (console, console_prefixed, kmsg, journal, ...)
- DefaultStandardOutput/Error: reuse ExecOutputType from common
- DefaultMemory/CPU/IOPressureWatch: reuse CGroupPressureWatch from common
- DefaultOOMPolicy: new enum (continue, stop, kill)
- CtrlAltDelBurstAction: reuse EmergencyAction from common

Output serialization updated to use JSON_BUILD_PAIR_ENUM for automatic
underscorification of dash-containing values.

Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-14 02:10:52 -07:00
Luca Boccassi 275ec1160b importd: harden curl file protocol handling
With old libcurl versions file:// can get redirects which can be messy, while
the new version rejects them. Set an option to explicit block them.
2026-04-14 10:45:38 +02:00
Zbigniew Jędrzejewski-Szmek c5b4aeefcb Assorted cleanups and fixes (#41626) 2026-04-14 09:10:16 +02:00
Christian Brauner 1006f6ca4c NEWS: pre-announce removal of /run/boot-loader-entries/ support in lo… (#41622)
…gind

logind could read UAPI.1 Boot Loader Spec entries from
/run/boot-loader-entries/ in addition to ESP/XBOOTLDR. This was pretty
half-assed, and to my knowledge was never actually used much.

Let's remove support for it and simplify our codebase.

Let's schedule it for removal via NEWS in a future version, to give
people a chance to speak up.
2026-04-14 08:54:33 +02:00
Sriman Achanta 765416cae6 hwdb: Add extended SteelSeries Arctis headset device support (#41628)
Add USB device IDs for additional SteelSeries Arctis headset models to
the sound card hardware database.

Newly added device IDs:

- Arctis Nova 7x v2 (22AD)
- Arctis Nova 7 Diablo IV (22A9)
- Arctis Nova 7X (22A4)
- Arctis Nova 7X (22A5)
- Arctis Nova 7P V2 (22A7)
2026-04-14 01:08:30 +01:00
Luca Boccassi f125fc6a22 journal-upload: also disable VERIFYHOST when --trust=all is used
When --trust=all disables CURLOPT_SSL_VERIFYPEER, the residual
CURLOPT_SSL_VERIFYHOST check is ineffective since an attacker can
present a self-signed certificate with the expected hostname. Disable
both for consistency and log that server certificate verification is
disabled.

Follow-up for 8847551bcb
2026-04-13 22:11:50 +01:00
Luca Boccassi a9e9288288 machined: pass user as positional argument in machine_default_shell_args()
Instead of interpolating the user name directly into the sh -c script
body via asprintf %s, pass it as a positional parameter ($1) in a
separate argv entry. This avoids the user string being parsed as part
of the shell script syntax.

Also validate the user name in bus_machine_method_open_shell() with
valid_user_group_name(), matching the validation already done on the
Varlink path via json_dispatch_const_user_group_name().

Follow-up for 49af9e1368
2026-04-13 22:11:50 +01:00
Luca Boccassi 4bf9db7314 logind: reject wall messages containing control characters
method_set_wall_message() and the property setter only checked the
message length but not its content. Since wall messages are broadcast
to all TTYs, control characters in the message could interfere with
terminal state. Reject messages containing control characters other
than newline and tab.

Follow-up for 9ef15026c0
Follow-up for e2fa5721c3
2026-04-13 22:11:50 +01:00
Luca Boccassi 04f32dddd7 core: check selinux access on each unit when listing
Units might have different access rules, so check the access on each
unit when querying the full list.
2026-04-13 22:11:50 +01:00
Luca Boccassi 26fd286210 core: add missing SELinux access checks when listing units
Add mac_selinux_unit_access_check_varlink() to the unit enumeration
loop in vl_method_list_units(), silently skipping units the caller
is not permitted to see, matching the D-Bus ListUnits behavior.
Add mac_selinux_access_check_varlink() to vl_method_describe_manager().

Follow-up for 472abf7bec
Follow-up for 736349958e
2026-04-13 22:11:43 +01:00
Christian Brauner 73cbf95d25 vmspawn: Support RUNTIME_DIRECTORY again (#41619)
In ccecae0efd ("vmspawn: use machine name in runtime directory path")
support for RUNTIME_DIRECTORY was dropped which makes it difficult to
run systemd-vmspawn in a service unit which doesn't have write access to
the regular /run but should use its own managed RUNTIME_DIRECTORY. What
worked before was --keep-unit --system but we can't use XDG_RUNTIME_DIR
and --user because then --keep-unit breaks which we need because it
can't create a scope as there is no session. Switch back to
runtime_directory which handles RUNTIME_DIRECTORY and tells us whether
we should use it as is without later cleanup or if we need to use the
regular path where we create and delete the directory ourselves.
2026-04-13 19:46:55 +02:00
Lennart Poettering 1716467bfa NEWS: pre-announce removal of /run/boot-loader-entries/ support in logind
logind could read UAPI.1 Boot Loader Spec entries from
/run/boot-loader-entries/ in addition to ESP/XBOOTLDR. This was pretty
half-assed, and to my knowledge was never actually used much.

Let's remove support for it and simplify our codebase.

Let's schedule it for removal via NEWS in a future version, to give
people a chance to speak up.
2026-04-13 17:53:12 +02:00
rusty-snake b40ed2067f docs: fix capability name, it's CAP_MKNOD not CAP_SYS_MKNOD (#41621) 2026-04-13 16:41:33 +01:00
Daan De Meyer 8383d033cc ci: Two claude-review fixes
- Use persist-credentials: false for actions/checkout, so we don't
  leak the github token credentials to subsequent jobs.
- Remove one / from the Edit/Write permissions. Currently, with the
  absolute path from github.workspace, we expand to three slashes while
  we only need two.
2026-04-13 16:30:15 +01:00
Ivan Kruglov 29c00e0295 varlink: move shared enum types to varlink-idl-common
Move ExecOutputType, CGroupPressureWatch, EmergencyAction and
ManagedOOMMode enum type definitions from varlink-io.systemd.Unit to
varlink-idl-common, as these types are shared across multiple varlink
interfaces.

Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 05:37:08 -07:00
Kai Lüke 47237cf623 vmspawn: Support RUNTIME_DIRECTORY again
In ccecae0efd ("vmspawn: use machine name in runtime directory path")
support for RUNTIME_DIRECTORY was dropped which makes it difficult to
run systemd-vmspawn in a service unit which doesn't have write access
to the regular /run but should use its own managed RUNTIME_DIRECTORY.
What worked before was --keep-unit --system but we can't use
XDG_RUNTIME_DIR and --user because then --keep-unit breaks which
we need because it can't create a scope as there is no session.
Switch back to runtime_directory which handles RUNTIME_DIRECTORY and
tells us whether we should use it as is without later cleanup or if we
need to use the regular path where we create and delete the directory
ourselves.
2026-04-13 21:33:15 +09:00
Zbigniew Jędrzejewski-Szmek 1726224b07 many: final final set of coccinelle check-pointer-deref tweaks (#41595)
I promised in https://github.com/systemd/systemd/pull/41426 that its the
final update for coccinelle pointer deref checks. However it turned out
there is this coccinelle/parsing_hacks.h that I wasn't aware of. The
file missed some important things like _cleanup_(x) that prevented
coccinelle to check a bunch of functions.

This PR adds some missing defines to the parsing_hacks.h and fixes the
missing asserts(). I apologize that its a bit long (and frankly boring)
and that I missed this earlier.

The last commit contains one small behavior change (ret in
sd_varlink_idl_parse() is now really optional) but the big one is very
mechanical.
2026-04-13 13:59:24 +02:00
Lennart Poettering 4fdc4af7f6 stat-util: use stat_verify_xyz() and friends more (#41613) 2026-04-13 13:39:47 +02:00
Arnout Engelen 086707ba79 run: allow setting output format
This is useful when moving from `--pty` or `--pipe` to using
`--verbose`: you can use `--verbose-output=cat` to get similar output on
stdout while still having all of the advantages of `--verbose` over the
other options.
2026-04-13 13:38:04 +02:00
Lennart Poettering 7977c14273 stat-util: always check S_ISDIR() before S_ISLNK()
Check S_ISDIR() before S_ISLINK() for all stat_verify_xyz() helpers
first, where we check them. Just to ensure we systematically return the
same errors.
2026-04-13 13:20:43 +02:00
Lennart Poettering aa0da09127 stat-util: also add stat_verify_char() and use it everywhere 2026-04-13 13:20:43 +02:00
Lennart Poettering 4eb60e3160 socket-netlink: use stat_verify_socket() more 2026-04-13 13:20:43 +02:00
Lennart Poettering 4031a73a4b tree-wide: use stat_verify_directory() more 2026-04-13 13:20:43 +02:00
Lennart Poettering 8e0756c0b5 tree-wide: use stat_verify_regular() more 2026-04-13 13:20:43 +02:00
Lennart Poettering bda7e91337 stat-util: also introduce stat_verify_block() and use it everywhere 2026-04-13 13:20:43 +02:00
Lennart Poettering 7f2410deb1 stat-util: add shortcut for fd_verify_symlink()
We have a similar shortcut in the other fd_verify_xyz() calls, let's add
it here too, just for completion's sake.
2026-04-13 13:20:43 +02:00
Lennart Poettering 596c0a259d tree-wide: make more use of stat_verify_device_node() 2026-04-13 13:20:43 +02:00
Lennart Poettering 6b0a3ef8c7 stat-util: introduce a common (stat|fd)_verify_regular_or_block() helper
We already had one in repart.c, let's generalize it, and use it
everywhere.
2026-04-13 13:20:42 +02:00
Milan Kyselica 2c664b9531 boot: fix loop bound and OOB in devicetree_get_compatible()
The loop used the byte offset end (struct_off + struct_size) as the
iteration limit, but cursor[i] indexes uint32_t words. This reads
past the struct block when end > size_words.

Use size_words (struct_size / sizeof(uint32_t)) which is the correct
number of words to iterate over.

Also fix a pre-existing OOB in the FDT_BEGIN_NODE handler: the guard
i >= size_words is always false inside the loop (since the loop
condition already ensures i < size_words), so cursor[++i] at the
boundary reads one word past the struct block. Use i + 1 >= size_words
to check before incrementing.

Fixes: https://github.com/systemd/systemd/issues/41590
2026-04-13 12:33:56 +02:00
Milan Kyselica c3c9cc7adb boot: fix integer overflow and division by zero in BMP splash parser
Bound image dimensions before computing row_size to prevent overflow
in the depth * x multiplication on 32-bit. Without this, crafted
dimensions like depth=32 x=0x10000001 wrap to a small row_size that
passes all subsequent checks.

Reject channel masks where all bits are set (popcount == 32), since
1U << 32 is undefined behavior and causes division by zero on
architectures where it evaluates to zero. Move the validation before
computing derived values for clarity. Use unsigned 1U in shifts to
avoid signed integer overflow UB for popcount == 31.

Also reject zero-width and zero-height images.

Fixes: https://github.com/systemd/systemd/issues/41589
2026-04-13 12:24:07 +02:00
Lennart Poettering 087733e348 core: use JSON_BUILD_CONST_STRING() where appropriate 2026-04-13 12:08:16 +02:00
Zbigniew Jędrzejewski-Szmek d091b0dd6a journal: limit decompress_blob() output to DATA_SIZE_MAX (#41604)
We already have checks in place during compression that limit the data
we compress, so they shouldn't decompress to anything larger than
DATA_SIZE_MAX unless they've been tampered with. Let's make this
explicit and limit all our decompress_blob() calls in journal-handling
code to that limit.

One possible scenario this should prevent is when one tries to open and
verify a journal file that contains a compression bomb in its payload:

```
$ ls -lh test.journal
-rw-rw-r--+ 1 fsumsal fsumsal 1.2M Apr 12 15:07 test.journal

$ systemd-run --user --wait --pipe -- build-local/journalctl --verify --file=$PWD/test.journal
Running as unit: run-p682422-i4875779.service
000110: Invalid hash (00000000 vs. 11e4948d73bdafdd)
000110: Invalid object contents: Bad message
File corruption detected at /home/fsumsal/repos/@systemd/systemd/test.journal:272 (of 1249896 bytes, 0%).
FAIL: /home/fsumsal/repos/@systemd/systemd/test.journal (Bad message)
          Finished with result: exit-code
Main processes terminated with: code=exited, status=1/FAILURE
               Service runtime: 48.051s
             CPU time consumed: 47.941s
                   Memory peak: 8G (swap: 0B)
```
Same could be, in theory, possible with just `journalctl --file=`, but
the reproducer would be a bit more complicated (haven't tried it, yet).

Lastly, the change in journal-remote is mostly hardening, as the maximum
input size to decompress_blob() there is mandated by MHD's connection
memory limit (set to JOURNAL_SERVER_MEMORY_MAX which is 128 KiB at the
time of writing), so the possible output size there is already quite
limited (e.g. ~800 - 900 MiB for xz-compressed data).
2026-04-13 12:02:11 +02:00
Zbigniew Jędrzejewski-Szmek 3e12cf85cd udev/scsi-id: hardening against malformed kernel data (#41585) 2026-04-13 11:53:43 +02:00
Daan De Meyer 4bbdc8a6a2 nspawn: Add --restrict-address-families= option
Add a new --restrict-address-families= command line option and
corresponding RestrictAddressFamilies= setting for .nspawn files to
restrict which socket address families may be used inside a container.

Many address families such as AF_VSOCK and AF_NETLINK are not
network-namespaced, so restricting access to them in containers
improves isolation. The option supports allowlist and denylist modes
(via ~ prefix), as well as "none" to block all families, matching the
semantics of RestrictAddressFamilies= in unit files.

The address family parsing logic is extracted into a shared
parse_address_families() helper in parse-helpers.c, which is now also
used by config_parse_address_families() in load-fragment.c.

This is currently opt-in. In a future version, the default will be
changed to restrict address families to AF_INET, AF_INET6 and AF_UNIX.
2026-04-13 11:14:11 +02:00
Daan De Meyer 4c9ce728e7 mkosi: Drop kexec-tools
Not needed anymore now that we use kexec_file_load().
2026-04-13 11:13:04 +02:00
Daan De Meyer e107c7ead0 systemctl: replace kexec-tools dependency with direct kexec_file_load() syscall
Replace the fork+exec of /usr/bin/kexec in load_kexec_kernel() with a
direct kexec_file_load() syscall, removing the runtime dependency on
kexec-tools for systemctl kexec.

The kexec_file_load() syscall (available since Linux 3.17) accepts
kernel and initrd file descriptors directly, letting the kernel handle
image parsing, segment setup, and purgatory internally. This is much
simpler than the older kexec_load() syscall which requires complex
userspace setup of memory segments and boot protocol structures — that
complexity is the raison d'être of kexec-tools.

The implementation follows the established libc wrapper pattern: a
missing_kexec_file_load() fallback in src/libc/kexec.c calls the
syscall directly when glibc doesn't provide a wrapper (which is
currently always the case). The syscall is not available on all
architectures — alpha, i386, ia64, m68k, mips, sh, and sparc lack
__NR_kexec_file_load — so the wrapper and caller are guarded with
HAVE_KEXEC_FILE_LOAD_SYSCALL to compile cleanly everywhere.

When kexec_file_load() rejects the kernel image with ENOEXEC (e.g. the
image is compressed or wrapped in a PE container that the kernel's kexec
handler doesn't understand natively), we attempt to unwrap/decompress
and retry. This is effectively the same decompression and extraction
logic that already lives in src/ukify/ukify.py (maybe_decompress() and
get_zboot_kernel()), now implemented in C so that systemctl can handle
it natively without shelling out to external tools:

 - Compressed kernels (Image.gz, Image.zst, Image.xz, Image.lz4): the
   format is detected by magic bytes (per RFC 1952, RFC 8878,
   tukaani.org xz spec, and lz4 frame format spec) and decompressed to
   a memfd using the existing decompress_stream_*() infrastructure plus
   the new gzip support from the previous commit. This is primarily
   needed on arm64 where kexec_file_load() only accepts raw Image files.
   On x86_64, bzImage is already the native format and works directly.

 - EFI ZBOOT PE images (vmlinuz.efi): detected by "MZ" + "zimg" magic
   at the start of the file. The compressed payload offset, size, and
   compression type are read from the ZBOOT header defined in
   linux/drivers/firmware/efi/libstub/zboot-header.S.

 - Unified Kernel Images (UKI): detected as PE files with a .linux
   section via the existing pe_is_uki() infrastructure. The .linux
   section (kernel) and optionally .initrd section are extracted to
   memfds. When a UKI provides an embedded initrd and the boot entry
   doesn't specify one separately, the embedded initrd is used.

The try-first-then-decompress approach means we never decompress
unnecessarily: on x86_64 the first kexec_file_load() call succeeds
immediately with the raw bzImage, and on architectures where the
kernel's kexec handler natively understands PE (like LoongArch with
kexec_efi_ops), ZBOOT/UKI images work without decompression too.

If kexec_file_load() is unavailable (architectures without the syscall)
or all attempts fail, we fall back to forking+execing the kexec binary.
This preserves compatibility on architectures like i386 and mips where
only the older kexec_load() syscall exists and kexec-tools is needed to
handle the complex userspace setup.

Co-developed-by: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 11:13:04 +02:00
Daan De Meyer 4d91b0366a libc: Add kexec_file_load() syscall wrapper
Allow tabs in UAPI headers in .gitattributes since they are copied
verbatim from the kernel.
2026-04-13 11:13:04 +02:00
Daan De Meyer 0a8578a6ee compress: rework decompressor_detect() on top of compression_detect_from_magic()
Replace the duplicated magic byte signatures in decompressor_detect()
with a call to the new compression_detect_from_magic() helper and use a
switch statement to initialize the appropriate decompression context.
2026-04-13 11:13:04 +02:00
Lennart Poettering e700d5134d time-util: encode our assumption that clock_gettime() never can return 0 or USEC_INFINITY
We generally assume that valid times returned by clock_gettime() are > 0
and < USEC_INFINITY. If this wouldn't hold all kinds of things would
break, because we couldn't distuingish our niche values from regular
values anymore.

Let's hence encode our assumptions in C, already to help static
analyzers and LLMs.

Inspired by: https://github.com/systemd/systemd/pull/41601#pullrequestreview-4094645891
2026-04-13 08:52:43 +02:00
Luca Boccassi 7fbdc6a8eb udev/scsi-id: various typing refactorings 2026-04-12 21:32:16 +01:00
Luca Boccassi 06d3f37336 udev/scsi-id: check for invalid header from kernel buffer 2026-04-12 21:28:48 +01:00
Luca Boccassi 5f700d148c udev/scsi-id: check for invalid chars in various fields received from the kernel
Follow-up for 16325b35fa
2026-04-12 21:28:48 +01:00