Vitaly Kuznetsov [Fri, 27 Feb 2026 13:20:20 +0000 (14:20 +0100)]
cryptsetup-tokens: Print tpm2-primary-alg: only when it is known
When 'tpm2-primary-alg' is missing in LUKS JSON token, the output of
'cryptsetup luksDump' is always:
tpm2-primary-alg: ecc
because tpm2_parse_luks2_json() returns the default (TPM2_ALG_ECC). This can be
misleading and wrong. Make tpm2_parse_luks2_json() return the reality and move
the default to tpm2_unseal().
Vitaly Kuznetsov [Fri, 27 Feb 2026 12:46:07 +0000 (13:46 +0100)]
cryptenroll: Save primary algorithm type to the LUKS token
'tpm2-primary-alg' field is currently unset in LUKS JSON token both for the
case when SRK was used for enrolling (--tpm2-device-key=) and for the case when
SRK was obtained/generated (--tpm2-device=). While this information is not
really needed for unsealing (the sealed object itself has key type in it), it
may be convenient to see key type in e.g. 'cryptsetup luksDump' in the
situations where key type matters. Since 'tpm2-primary-alg' is already defined,
just set it properly in all cases.
Val Markovic [Mon, 2 Mar 2026 03:38:35 +0000 (04:38 +0100)]
man: improve documentation for RestartSteps (#40879)
I found the existing explanation of RestartSteps to be simply
impenetrable. Even providing the full docs context to several of our new
AI overlords resulted in wildly different (and completely incorrect)
explanations of the final restart intervals.
Digging through the code, I found the restart delay computation in
`service_restart_usec_next` in `src/core/service.c`.
I've updated the documentation for RestartSteps with an example,
suggested value range and a detailed enough explanation that accurately
describes the current behavior.
noxiouz [Fri, 27 Feb 2026 00:02:12 +0000 (00:02 +0000)]
import: fix AlreadyInProgress Varlink error missing remote field
The handler sends the remote URL as a parameter via sd_varlink_errorbo()
but the IDL declared the error with no fields, making the payload
undiscoverable via introspection.
Jeremy Kerr [Tue, 9 Dec 2025 13:22:55 +0000 (22:22 +0900)]
udev-builtin-net_id: fix construction of USB specifier-based names
Commit 0bac1ed242 ("tree-wide: Fix constness issues with newer glibc")
split a temporary var in get_usb_specifier to const and non-const
versions, but missed converting a couple of uses. This means we get
names of with components of:
port: uN
config: cC.I
interface: iC.I
instead of:
port: uN
config: cC
interface: iI
This results in net names like enu1c1.0i1.0, as we also no longer hit
the config==1 and interf==0 elision cases.
Change the config portion handling to start from the correct position,
and the earlier check for NULL.
Daan De Meyer [Tue, 25 Nov 2025 15:46:04 +0000 (16:46 +0100)]
tree-wide: Fix constness issues with newer glibc
Latest glibc uses _Generic to have strstr() and other functions return
const char* or char* based on whether the input is a const char* or a
char*. This causes build failures as we previously always expected a char*.
Let's fix the compilation failures and add our own macros similar to glibc's
to have string functions that return a mutable or const pointer depending on
the input.
Luca Boccassi [Fri, 17 Oct 2025 13:00:23 +0000 (14:00 +0100)]
ci: re-enable bpf-framework option for build and unit test jobs
Use the same trickery we do in the package build and search for
the actual bpftool binary. For the CI job any one we find is
good enough.
When we switch all jobs to 26.04 we can drop all of this.
Luca Boccassi [Wed, 25 Feb 2026 23:12:28 +0000 (23:12 +0000)]
mkosi: explicitly add mount package to build image
Some dependency changed in testing and it's not pulled in anymore:
‣ Running build script /home/runner/work/systemd/systemd/mkosi/mkosi.images/build/mkosi.conf.d/debian-ubuntu/mkosi.build.chroot…
/work/build-script: line 35: mount: command not found
‣ /work/build-script failed with non-zero exit code 127
‣ (Maybe a program was not found or the script interpreter (e.g. bash) is not installed?)
FAILED: [code=127] mkosi
Nick Rosbrook [Mon, 23 Feb 2026 20:25:27 +0000 (15:25 -0500)]
seccomp-util: add lsm_get_self_attr and lsm_list_modules to @default
These syscalls are part of a newer kernel API to replace interaction
with /proc/self/attr, with the goal of allowing LSM stacking. These are
being used now by e.g. libapparmor, so should be more easily available
to services using seccomp filtering.
sd-netlink: pin reply slot while we execute callback
The callback might drop the last ref to the slot object, and we still
want to access it. Hence do what we usually do in these cases: keep an
extra reference while processing the callback.
network: enable LLDP for links that use only link-local addressing
Links with link-local-only communication are typically peer-to-peer
links between two laptops or similar. In such cases it makes sense to be
able to see which device one is specifically connected to, hence let's
just enable LLDP for it. This doesn't leak any data really, given that
this is inherently local, and typically only used between isolated
systems that are under the same user's possession.
Background: I recently connected multiple laptops via thunderbolt networking
and was kinda annoyed not being able to see what system I was actually
talking to.
(Also, the file touched here is an example only anyway, so even if this
would leak too much info, it's not in effect by default)
repart: return 1 from probe_sector_size_prefer_ioctl() on block device success
probe_sector_size() returns 1 when it successfully determines the sector size,
0 when falling back to the default. blockdev_get_sector_size() returns 0 on
success. probe_sector_size_prefer_ioctl() was passing blockdev_get_sector_size()
return value through directly, so caller is checking r > 0 to detect a
successfully probed sector size never saw it for block devices.
In context_load_partition_table(), this caused fs_secsz to stay at 4096 bytes
even on 512-byte sector block devices, making verity hash partition sizes wrong
unless --sector-size=512 was passed explicitly.
Fix by returning 1 on success from the block device path to match probe_sector_size()
convention.
Kai Lüke [Thu, 19 Feb 2026 07:01:06 +0000 (16:01 +0900)]
openssl-util: pass the UI callback for interactive PIN prompts
Observed with the tpm2 provider and the tpm2tss engine was that the
auth process failed because the provider/engine could not ask for the
PIN through the callback, resulting in:
"Failed to load private key from ...: Input/output error"
Apparently the default UI method is not enough and the key setup
functions expect an explicit method.
Pass the existing UI method through as callback for the key setup.
Dmitry V. Levin [Wed, 18 Feb 2026 08:00:00 +0000 (08:00 +0000)]
github/dependabot: set cooldown period
By default, Dependabot does not perform any cooldown on dependency updates.
In other words, a regularly scheduled Dependabot run may perform an update
on a dependency that was just released moments before the run began.
This presents both stability and supply-chain security risks.
To mitigate these risks, explicitly set Dependabot cooldown period to 7 days.
Daan De Meyer [Fri, 13 Feb 2026 11:24:49 +0000 (12:24 +0100)]
user-util: Don't setgroups() if /proc/self/gid_map is empty
If /proc/self/gid_map is empty, the kernel will refuse setgroups(),
so don't attempt it if that's the case on top of the /proc/self/setgroups
check we already have.
Chris Down [Sat, 14 Feb 2026 16:40:14 +0000 (00:40 +0800)]
string-util: Prevent infinite loop pegging CPU on malformed ESC input
string_has_ansi_sequence() currently does this to look for ESC input:
t = memchr(s, 0x1B, ...)
So each iteration re-searches from the original start pointer. But if we
find an ESC byte that does *not* start a valid ANSI sequence (like "\x1B
", or an ESC at the end of the string), then ansi_sequence_length()
returns 0, and if that ESC is still in the search window, we will just
spin consuming 100% CPU forever.
Fix this by always advancing past rejected ESC bytes.
Daan De Meyer [Thu, 12 Feb 2026 19:34:27 +0000 (20:34 +0100)]
TEST-72-SYSUPDATE: Use some very long partition names
To catch issues like https://github.com/systemd/systemd/issues/40658.
The commit that fixes that issue can make the name even longer to ensure
we don't regress again in this regard.
Luca Boccassi [Thu, 5 Feb 2026 00:39:35 +0000 (00:39 +0000)]
journald: set a lower size limit for FDs from unpriv processes
Unprivileged processes can send 768M in a FD-based message to journald,
which will be malloc'ed in one go, likely causing memory issues.
Set the limit for unprivileged users to 24M.
Allow coredumps as an exception, since we always allowed storing
up to the 768M max core files in the journal.
In my testing I switched building my locally run CI integration tests to
ArchLinux and realized that for that the default sizes don't work
anymore, the images are larger than the space allocated. Let's bump the
size by 50% for the relevant disk images.
Luca Boccassi [Wed, 25 Feb 2026 11:16:28 +0000 (11:16 +0000)]
mkosi: add groupadd/groupmod to ASAN wrappers list
TEST-74-AUX-UTILS.sh[3789]: + groupadd haldo
TEST-74-AUX-UTILS.sh[3875]: ==3875==ASan runtime does not come first in initial library list; you should either link runtime to your application or manually preload it with LD_PRELOAD.
Oblivionsage [Wed, 18 Feb 2026 17:22:48 +0000 (18:22 +0100)]
pe-binary: wrap remaining LE fields with byte-swap macros
Follow-up to 02cab70acf5ca67e838d0d34860baacbf9fc3b6c. pe_hash(),
section_offset_cmp() and uki_hash() still had a bunch of raw accesses
to LE fields (e_lfanew, SizeOfHeaders, PointerToRawData, SizeOfRawData,
VirtualSize, certificate_table->Size) without le32toh(), so they'd
produce garbage on big-endian.
Also wrap VirtualSize in bootspec.c for consistency.
Oblivionsage [Tue, 17 Feb 2026 18:39:05 +0000 (19:39 +0100)]
pe-binary: fix missing le16toh() on NumberOfSections in pe_hash/uki_hash
pe_hash() and uki_hash() pass pe_header->pe.NumberOfSections directly
to typesafe_qsort() and FOREACH_ARRAY() without le16toh(). On
big-endian (s390x), NumberOfSections=3 gets read as 0x0300 (768),
while pe_load_sections() correctly converts it and only allocates 3
sections. This makes qsort process 768 elements on a 3-element
buffer, causing a heap-buffer-overflow (confirmed with ASAN on
native s390x).
Wrap all three raw usages with le16toh() to match pe_load_sections().
The line to set opterr=0 was added in the initial commit in 3d090cc6f34e5970765dd1e7ee5e648a056d180d. But afaict, this never worked as
intended, because ':' must be the first char in optstring given to
getopt_long() for it to return ':' for a missing option value. Since
this wasn't set, getopt_long() would return '?', and the missing value
would be handled as an unknown option:
$ build/systemd-journal-upload --key
Unknown option --key.
$ build/systemd-journal-upload --asdf
Unknown option --asdf.
Let's just do the standard thing:
$ build/systemd-journal-upload --key
build/systemd-journal-upload: option '--key' requires an argument
$ build/systemd-journal-upload --asdf
build/systemd-journal-upload: unrecognized option '--asdf'
When we say '-n --iterations=N' in --help, this means that the program
can be invoked with '-n N' or '--iterations=N' or '--iterations N'.
(The short option is specified without the argument.)
Here we tried to use '-p --order=path' to mean that the program can be
invoked with '-p' or '--order=path', but that is incompatible with the
established convention.
* e3642f81d3 kmod: Only use --modname if available
* ddea81d81e arch: Download archlinux-keyring with pacman
* 4a44e1831b Remove unneeded lambdas
* 9c3d23757c Configure pyright included files
* 5e037d514c qemu: Register with systemd-machined in user session
* c4c3d793d0 Create package cache dir before invoking pacman
* d53761c4dd distribution: do not default to release=VERSION_ID for openSUSE Tumbleweed
* c5bc9138fc Wrap build_microcode_initrd in complete_step
* 635159975d Fix typo in manpage
* 59f5f0741e mkosi-addon: drop Output=addon, addon.py already has a default
* be85b8ca0b sandbox: return raw error code from the kernel and friends on failure
* 56f25c1a41 config: replace deprecated sandbox verb with box in help message
* ae24c527d7 sandbox: fix wrong errno passed to OSError()
* e7b9612760 verity: do not copy signing cert in addons/portables/extensions
* f3a029b736 Bump version to 27~devel
* 84af20892b Release 26
* 3fcd3a0fde Adjust logging messages for kmod/fw resolution
* d44aae12b4 Revert "Do not try to install packages that are listed in RemovePackages="
* 1873ad0184 portable: Make sure mountpoints exist in the image
* 5dc693feb0 initrd: Inherit keymap, timezone, hostname and rootpw by default
* 9e31235211 pacman: Make sure hookdir exists
* 20009b7f48 make_image: log systemd-repart *.conf files at the --debug level
* b94b415db9 run: Increase string limit for strace when debugging sandbox
* 9f6d9405d6 Ring the terminal bell after the last image has been built
* b509b4246d Add glob in default initrd to exclude some exotic drivers
* 189394b8b9 Allow KernelModules= globs to also match relative to modules root dir
* 92bd086e4e zypper: add --force-resolution flag
* 3637749702 kmod: Only add fully resolved fw path if it exists
* d41ac276c9 Add details to KernelModulesInitrd= doc
* 1b6960ddb1 Fix SplitArtifacts=repart-definitions for addons
* 07464f38d6 Add log_step call in build_kernel_modules_initrd
* 18f5885362 Use proper constants for ansi colors
* 454c1602b6 mkosi-obs: add SplitArtifacts=repart-definitions and use it
* 9e57461af6 Copy repart definitions to staging directory
* 1acab18874 Add SplitArtifacts=repart-definitions
* c5c5c225e8 mkosi-obs: always include verity certificate
* ac5babb8e0 Revert "Use Path.relative_to instead of Path.parts"
* cbb1daeb76 action: Use environment variables instead of inputs
* 97c81eef72 portable: support split roothash
James Le Cuirot [Tue, 27 Jan 2026 17:12:34 +0000 (17:12 +0000)]
efi-string: Unquote single-quoted strings as well as double
This code is used to read data copied from /etc/os-release. According to
the spec[1], values can be enclosed in single quotes or double quotes.
Not handling single quotes results in the quotes appearing in the
systemd-boot menu, e.g. 'Gentoo Linux'.
pid1: shorten message about jobs skipped after failed condition checks
I was looking at some logs on a console, and because of the lengthy message,
the actually interesting part, i.e. what condition failed, didn't even fit
on the screen. Let's make the sentence legible but brief.
Daan De Meyer [Fri, 16 Jan 2026 20:21:06 +0000 (21:21 +0100)]
core: Improve logging when we cannot create destination mountpoint
If we fail to create a parent directory, then the error from
make_mount_point_inode_from_path() will always be
"No such file or directory" which doesn't tell us anything. Add logging
for the mkdir_parents() call as well so we get a useful error.
Yu Watanabe [Sat, 31 Jan 2026 17:37:07 +0000 (02:37 +0900)]
mkosi: workaround issue in mdadm-4.5 + linux-6.18
After debian updated the kernel from 6.17 to 6.18, mdadm command fails
with the following:
```
+ mdadm --create /dev/md/mdmirror ...
mdadm: size set to 64512K
mdadm: Can't open /sys/module/md_mod/parameters/legacy_async_del_gendisk
mdadm: init md module parameters fail
```
This seems a bug in mdadm, and fix is already merged in the upstream:
https://github.com/md-raid-utilities/mdadm/pull/228
Until the fix is backported, let's workaround the issue.
See also: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1125390
Nick Rosbrook [Mon, 19 Jan 2026 21:09:12 +0000 (16:09 -0500)]
test: use journalctl -n option instead of piping to head
On Ubuntu's test infrastructure for the development series, this test
often fails when piping the journal output to head. The cause is
unclear, but possibly related to Ubuntu's use of uutils coreutils.
Workaround this by just using journalctl's -n flag, which removes the
need for piping output to head.
Philip Withnall [Tue, 27 Jan 2026 15:25:08 +0000 (15:25 +0000)]
docs: Add a diagram for the internals of sysupdate
I had to sketch this out before I could get the internals of
systemd-sysupdate straight in my head, particularly around how an
`UpdateSet` points to one `Instance` from each of a set of `Resource`s,
and those `Instance`s are either all sources or all targets.
Hopefully this is useful to the next person to look at the code.
Jörg Behrmann [Fri, 23 Jan 2026 12:55:51 +0000 (13:55 +0100)]
kernel-install: handle removal unsuccessful UKIs and loader entries separately
When a tries file exists, 90-uki-copy.install removes a previous UKI of the
same kernel version and all it's unbooted variants. This removal is guarded
behind a check for the existence of the already booted UKI, i.e. if uki.efi
already exists, uki.efi and uki+*.efi will be removed.
This leaves the edge case that if uki.efi does not exist, but only an unbooted,
e.g. uki+3.efi, it will not be removed. This is not a problem, if the number of
tries is constant between both builds, since a new uki+3.efi would overwrite
the existing one, but if the number of tries is changed to, e.g. uki+5.efi, we
are left with both uki+3.efi and uki+5.efi.
/usr/share/ is a directory commonly accessed by various tools, hence we
really should make sure we umount it lazily (MNT_DETACH), since
otherwise there's a good chance that the umount might simply fail.
Mike Yuan [Sat, 24 Jan 2026 17:33:05 +0000 (18:33 +0100)]
sd-event: unpoison memory returned by epoll_pwait2()
Our fuzzer CI recently got bumped to Ubuntu 24.04 with
glibc >= 2.35. Apparently msan is not happy with the new
epoll_pwait2(), hence explicitly mark the memory region
as initialized.