* cde07547ab Update changelog for 261~rc3-1 release
* 13a29e5eda Drop unused Lintian overrides
* 84c4af7e23 Drop now-autogenerated dlopen recommends/suggests
* 76995069a0 Drop dlopen:Depends from libsystemd-dev
* 91bb1e5423 Add ${dlopen:Depends} placeholder to all packages shipping ELF binaries
* 7e333f2b9c Drop bpftool build-dep workaround for Jammy/Noble
* 8a17f61489 Update changelog for 261~rc2-1 release
* 58ad925b52 Drop patches, all merged upstream
* e53db5cc8f Move conflict with runit helper to sd-sysv
* adb081fde6 Workaround piuparts issue with / permissions
* 457f16e3cf Clean up autovt@ alias on purge
* bc0bd48fc8 Update changelog for 261~rc1-1 release
* 537d92f8ae Force linking against libm
* 87622cc5ee Backport patch to skip test-pressure in autopkgtest
* 5b7253e3f9 Update symbols file for new version
* bcf39279f8 Backport patch to fix unit test in gitlab CI
* e654d67b76 Install new files for upstream release
* 9b724fd2c1 Bump Standards-version to 4.7.4, no changes
Luca Boccassi [Thu, 4 Jun 2026 13:44:09 +0000 (14:44 +0100)]
mkosi: pull in linux-tools-generic for jammy/noble
The build dependency is dropped from the package as it breaks
resolute builds, pull in manually in jammy/noble, as it's
needed for the 'real' bpftool binary
* 60ed8c964f ubuntu: Don't treat linux-tools-xxx as a kernel package
* 24e5e532ab obs: enable PR CI workflow
* 5edcd2c5ca action: skip install of unavailable packages
* 4c18bc115b sandbox: Make seccomp work on alternative arches
* a91c8730e2 tests: Mark install tests and run them separately
* 923f72ea63 Fix linter unit tests at package build time
* 3f4bee3392 tests: Avoid leading underscore in helper function
* b2f04776c4 docs: Document debugging of failed sandbox commands
* 461a1dd290 run: Show complete sandbox command, factor out its logging
* d74c0b03d9 Don't add El Torito boot catalog for BIOS/grub images by default
* b0f9525c2c tests: Move unit tests from GitHub workflow into pytest
* 2889b5599b run: Add `cwd` kwarg to run()/spawn()
* 3f7de100b8 sandbox: Fix pyright "possibly unbound variable" errors
* 4cb9f337e2 gitignore: Add generated man pages and zipapp builddir
* 49c1c78f3f pytest: Restrict discovery to tests/
* a9d7ab5e64 finalize_scripts: tighten the PATH-strip condition to actual self-exec
* 145f4c259b sandbox: Add --debug option
* df43e4007d Mount /etc/resolv.conf symlink into sandbox
Luca Boccassi [Thu, 4 Jun 2026 10:54:53 +0000 (11:54 +0100)]
test: wrap sd-run call with timeout to avoid long hangs in TEST-54-CREDS
This has been observed to get stuck in an ASAN run, so wrap it
in a timeout call to at least get it to fail fast and hopefully
get better logs rather than a testbed timeout.
Valentin David [Wed, 3 Jun 2026 20:10:49 +0000 (22:10 +0200)]
units: Run systemd-pcrnvdone in initrd
The measurement that systemd-pcrnvdone corresponds to
`src/pcrlock/pcrlock.d/770-nvpcr-separator.pcrlock`, and 770 is supposed to
happen in the initrd (which ends at 800).
Derek J. Clark [Wed, 3 Jun 2026 22:08:22 +0000 (15:08 -0700)]
(hwdb) Update MSI Claw Entries
- Add support for MSI Claw A8 BZ2EM.
- Switch to using rn vice pn as MSI uses a unique pn for variants of the
same model. This prevents needing to update this file when a low volume
variant is released (I.E. Polar White AI 8+).
Daan De Meyer [Wed, 3 Jun 2026 13:54:13 +0000 (13:54 +0000)]
fstab-generator: clear nosuid/nodev/noexec for root=bind: mounts
A bind mount inherits the mount flags of the file system the source
directory resides on. For root=bind: the source typically lives below
/run/ (e.g. a freshly unpacked tar image in /run/machines/), which is
mounted nosuid,nodev, so those flags propagated to /sysroot and broke
suid binaries (e.g. sudo) and device nodes on the booted system.
Default bind root mounts to dev,suid,exec instead, unless the user
overrides this via rootflags=.
Fixes: https://github.com/systemd/systemd/issues/41352 Co-developed-by: Claude Opus 4.8 <noreply@anthropic.com>
Daan De Meyer [Wed, 3 Jun 2026 14:03:39 +0000 (14:03 +0000)]
cryptsetup: document that keyfile-erase does not apply to auto-discovered key files
keyfile-erase only erases a key file explicitly configured in the third
field of crypttab. Key files automatically discovered in
/etc/cryptsetup-keys.d/ and /run/cryptsetup-keys.d/ are considered shared
resources not owned by an individual volume, and are never erased. Make
this explicit in the documentation and add a code comment clarifying the
intent.
Fixes: https://github.com/systemd/systemd/issues/41127 Co-developed-by: Claude Opus 4.8 <noreply@anthropic.com>
Since this was introduced I constantly find myself waiting for VMs to
shut down at the end of a test. This not only happens with mkosi
integration tests, but with other VM-based tests like for example
autopkgtest. In this example, this dracut test suite runtime is tripled
due to the artificial delay:
```
[ 5.813234] systemd-shutdown[1]: Syncing filesystems and block devices.
[ 5.814635] systemd-shutdown[1]: Delaying shutdown for 9s, in order to reach minimum uptime of 15s.
[ 8.816855] systemd-shutdown[1]: Delaying shutdown for 6s, in order to reach minimum uptime of 15s.
[ 11.819747] systemd-shutdown[1]: Delaying shutdown for 3s, in order to reach minimum uptime of 15s.
[ 14.822660] systemd-shutdown[1]: Delaying shutdown for 601ms, in order to reach minimum uptime of 15s.
[ 15.427777] systemd-shutdown[1]: Powering off.
[ 15.429681] sd 0:0:0:0: [sda] Synchronizing SCSI cache
[ 15.433620] ACPI: PM: Preparing to enter system sleep state S5
[ 15.435148] reboot: Power down
TEST: root filesystem on a ext4 filesystem with systemd and extensions [OK]
autopkgtest [19:39:12]: test 46-systemd-sysext: -----------------------]
autopkgtest [19:39:13]: test 46-systemd-sysext: - - - - - - - - - - results - - - - - - - - - -
46-systemd-sysext PASS
```
Contrary to what the comment claimed, the scrollback of a VM is _not_
cleared, EDK2 just prints many pages, and one can just scroll up (a
lot).
Do not delay by default on VMs. Move the check so that in both
containers and VMs users can override and force a delay with the env
var.
repart: when copying files into vfat or similar, do not set ownership
$ mkdir /var/tmp/files
$ touch /var/tmp/files/a
$ mkdir /var/tmp/conf
$ cat >>/var/tmp/conf/esp.conf
[Partition]
Type=esp
Format=vfat
CopyFiles=/var/tmp/files:/
$ truncate /var/tmp/disk -s 300M
$ sudo systemd-repart --dry-run=no --empty=require --definitions=/var/tmp/conf /var/tmp/disk
...
Populating vfat filesystem.
Failed to copy '...' to '/run/systemd/mount-root/': Operation not permitted
(sd-copy) failed with exit status 1.
The issue is that if there's a file owned by non-root and we try to copy
it into a newly-created DOS partition, fchown fails:
fchown(11</run/systemd/mount-root/...>, 1000, 1000) = -1 EPERM (Operation not permitted)
We want to ignore file ownership in such cases, so pass our own UID/GID
to copy_tree_at(), which turns the fchown into a noop and let's the
operation pass through.
repart: perform an early check for missing mkfs or fs contents
I was running repart in a VM, and if failed because mkfs.vfat was
not available. But if fails quite late in the process, possibly wasting
quite a bit of work. So add a check that catches some obvious cases
where repart would fail.
The condition of whether we have the root directory is complex,
determined in part by partition_target_prepare(). I didn't think it
was worth it to recreate the full logic in the check, so in some cases
it'll not miss cases. But that's still better than having no check ;)
Luca Boccassi [Wed, 3 Jun 2026 11:27:30 +0000 (12:27 +0100)]
test: fix short timeout in TEST-74-AUX-UTILS.busctl
This was likely a typo as the other timeouts are '30' instead of '3'. This
test occasionally fails with sanitizers which make everything slow. Bump it
to 30s like other timeouts in the same test.
Add DLOPEN macros that stamp the caller's ELF and use it to ensure executables list their dlopen dependencies (#42398)
Currently almost all the dlopens happen in libbasic or libshared code,
so the ELF dlopen notes all end up in libsystemd-shared. Many
distributions split this library and various binaries in separate
packages, and the library ends up with soft-dependencies, even though
many binaries are either completely useless or do not work at all with
the dlopen dependency. This also makes it impossible to know which
executable uses which dlopen dependency without inspecting the source
code.
If someone only wants to add the soft dependencies from libshared they
can just avoid parsing the executable binaries. By design the code in
libbasic/libshared still does the stamping too, at lower priorities, so
that libsystemd-shared will always list all the optional dependencies,
and if one wants to build a minimal system by default, they can just
parse libsystemd-shared dlopen notes, and ignore the individual
executables. But for many distribution the current setup is insufficient
and requires adding a ton of manual library dependencies, as many
executables become effectively broken or useless without the dlopen
dependencies installed (eg: resolved fails to start without libssl,
repart can do basically nothing without blkid, etc).
Add a new set of DLOPEN_<LIB> macros that wrap the dlopen_lib and also
pull in the ELF note voodoo, so that the callers get their ELF binaries
stamped too. Convert a bunch of callers to use the macro, and use
`required` dependencies for the callers that do not work without the
dlopen library being available.
The one caveat is that, in order to avoid duplicating the exact same
note in a binary due to multiple call sites, some `asm` voodoo is done
instead of the previous bare-C section-creating macro. The drawback of
this approach is that if `--gc-sections` is used to link the binary (as
we do), then binutils >= 2.36 is required for the `SHF_GNU_RETAIN` flag.
This effectively cuts off CentOS 9, so what I did here is adding an
override in meson to detect missing support, and drop `SHF_GNU_RETAIN`.
The build works, but on CentOS 9 there's no dlopen ELF notes anymore.
Given it's just that version, and it goes EOL next year, that seems ok
to me. The alternative is to drop the usage of `--gc-sections` on CentOS
9, or to accept duplicated notes everywhere, and both seem worse.
End result:
```
$ readelf --notes build/systemd-executor
Displaying notes found in: .note.gnu.property
Owner Data size Description
GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0
Properties: x86 ISA needed: x86-64-baseline
Displaying notes found in: .note.gnu.build-id
Owner Data size Description
GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring)
Build ID: 8a0c3db54adb79ae54e1432255011aa4ab583742
Displaying notes found in: .note.ABI-tag
Owner Data size Description
GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag)
OS: Linux, ABI: 3.2.0
Displaying notes found in: .note.dlopen
Owner Data size Description
FDO 0x0000006b FDO_DLOPEN_METADATA
Dlopen Metadata: [{"feature":"pam","description":"Support for LinuxPAM","priority":"recommended","soname":["libpam.so.0"]}]
FDO 0x0000007c FDO_DLOPEN_METADATA
Dlopen Metadata: [{"feature":"seccomp","description":"Support for Seccomp Sandboxes","priority":"recommended","soname":["libseccomp.so.2"]}]
FDO 0x00000090 FDO_DLOPEN_METADATA
Dlopen Metadata: [{"feature":"bpf","description":"Support firewalling and sandboxing with BPF","priority":"recommended","soname":["libbpf.so.1","libbpf.so.0"]}]
FDO 0x000000a0 FDO_DLOPEN_METADATA
Dlopen Metadata: [{"feature":"cryptsetup","description":"Support for disk encryption, integrity, and authentication","priority":"recommended","soname":["libcryptsetup.so.12"]}]
FDO 0x00000078 FDO_DLOPEN_METADATA
Dlopen Metadata: [{"feature":"mount","description":"Support for mount enumeration","priority":"recommended","soname":["libmount.so.1"]}]
$ readelf --notes build/systemd
Displaying notes found in: .note.gnu.property
Owner Data size Description
GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0
Properties: x86 ISA needed: x86-64-baseline
Displaying notes found in: .note.gnu.build-id
Owner Data size Description
GNU 0x00000014 NT_GNU_BUILD_ID (unique build ID bitstring)
Build ID: dcd4568842e32da3e71be27db3def51c6b459994
Displaying notes found in: .note.ABI-tag
Owner Data size Description
GNU 0x00000010 NT_GNU_ABI_TAG (ABI version tag)
OS: Linux, ABI: 3.2.0
Displaying notes found in: .note.dlopen
Owner Data size Description
FDO 0x00000075 FDO_DLOPEN_METADATA
Dlopen Metadata: [{"feature":"mount","description":"Support for mount enumeration","priority":"required","soname":["libmount.so.1"]}]
FDO 0x00000072 FDO_DLOPEN_METADATA
Dlopen Metadata: [{"feature":"selinux","description":"Support for SELinux","priority":"recommended","soname":["libselinux.so.1"]}]
```
lzwind [Tue, 2 Jun 2026 14:27:45 +0000 (22:27 +0800)]
network: fix ambiguous "without mode" wording in docs (#42428)
- In `systemd.network.xml`, replaced `"without mode"` with `"without static"`
to clarify that if an IPv6 address is specified without the explicit keyword
`static`, then `static` mode is assumed.
- The original wording was ambiguous because "mode" appears multiple
times in the surrounding context (referring to IPv6 link-local address
modes like `eui64`, `static`, etc.).
Daan De Meyer [Tue, 2 Jun 2026 13:45:19 +0000 (13:45 +0000)]
ci: make the review orchestrator emit one complete StructuredOutput call
The orchestrator repeatedly emitted StructuredOutput with only a long
`summary` and no `comments`, which the schema rejects as missing a required
property; one run burned 12 retries (and a large share of its output tokens)
re-typing rejected summaries before it shrank the summary enough to include
`comments`. Instruct it to build `comments` first, always include `comments`
and `resolve` (even when empty) in a single call, and keep the summary concise
so the detailed prose lives in the comments rather than being duplicated.
Co-developed-by: Claude Opus 4.8 <noreply@anthropic.com>
Daan De Meyer [Tue, 2 Jun 2026 12:33:01 +0000 (12:33 +0000)]
ci: review PRs through per-lens subagents with PR-specific lenses
Change the review fan-out from one subagent per commit to one subagent per
lens, each reviewing every commit through a single perspective. Four base
lenses (correctness/memory safety, lifetimes/concurrency, security, API/style)
always run; the orchestrator skims the diff and adds 1-3 PR-specific lenses
(e.g. a DNS protocol lens for resolved changes). A single generalist reviewer
tended to converge on one finding on large diffs; focused lenses dig deeper.
Commits are reviewed in chronological order via a commit-order.txt manifest,
since the SHA-named worktree dirs don't sort chronologically.
Co-developed-by: Claude Opus 4.8 <noreply@anthropic.com>
Luca Boccassi [Fri, 29 May 2026 17:17:25 +0000 (18:17 +0100)]
ci: add build coverage for riscv64
This is already a primary architecture in Ubuntu, and more distributions
are adding support for it. It's too slow for emulation, but we can at
least verify that compilation works.
Use the arm worker, for two reasons:
- it is already set up with ports.ubuntu.com so we don't have to muck
with apt sources manually
- it is used a lot less than the x86 worker
Luca Boccassi [Fri, 29 May 2026 18:06:44 +0000 (19:06 +0100)]
core: avoid false maybe-uninitialized warning
2026-05-29T18:00:43.7496388Z ../src/core/dynamic-user.c: In function ‘dynamic_user_realize’:
2026-05-29T18:00:43.7497098Z ../src/core/dynamic-user.c:436:29: error: ‘new_uid’ may be used uninitialized [-Werror=maybe-uninitialized]
2026-05-29T18:00:43.7497758Z 436 | num = new_uid;
2026-05-29T18:00:43.7498026Z | ~~~~^~~~~~~~~
2026-05-29T18:00:43.7498465Z ../src/core/dynamic-user.c:361:23: note: ‘new_uid’ was declared here
2026-05-29T18:00:43.7498802Z 361 | uid_t new_uid;
2026-05-29T18:00:43.7499039Z | ^~~~~~~
2026-05-29T18:00:43.7499315Z In file included from ../src/core/dynamic-user.c:23:
2026-05-29T18:00:43.7499651Z In function ‘dynamic_user_push’,
2026-05-29T18:00:43.7500063Z inlined from ‘dynamic_user_realize’ at ../src/core/dynamic-user.c:453:13:
2026-05-29T18:00:43.7501021Z ../src/basic/socket-util.h:131:63: error: ‘new_uid_lock_fd’ may be used uninitialized [-Werror=maybe-uninitialized]
2026-05-29T18:00:43.7501897Z 131 | #define send_one_fd_iov(transport_fd, fd, iov, iovlen, flags) send_one_fd_iov_sa(transport_fd, fd, iov, iovlen, NULL, 0, flags)
2026-05-29T18:00:43.7502530Z | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2026-05-29T18:00:43.7503145Z ../src/core/dynamic-user.c:320:16: note: in expansion of macro ‘send_one_fd_iov’
2026-05-29T18:00:43.7503647Z 320 | return send_one_fd_iov(d->storage_socket[1], lock_fd, &iov, 1, MSG_DONTWAIT);
2026-05-29T18:00:43.7504027Z | ^~~~~~~~~~~~~~~
2026-05-29T18:00:43.7504397Z ../src/core/dynamic-user.c: In function ‘dynamic_user_realize’:
2026-05-29T18:00:43.7504888Z ../src/core/dynamic-user.c:360:21: note: ‘new_uid_lock_fd’ was declared here
2026-05-29T18:00:43.7505256Z 360 | int new_uid_lock_fd;
2026-05-29T18:00:43.7505511Z | ^~~~~~~~~~~~~~~
2026-05-29T18:00:43.7505882Z ../src/core/dynamic-user.c: In function ‘dynamic_user_current’:
2026-05-29T18:00:43.7506461Z ../src/core/dynamic-user.c:468:15: error: ‘uid’ may be used uninitialized [-Werror=maybe-uninitialized]
2026-05-29T18:00:43.7506895Z 468 | uid_t uid;
2026-05-29T18:00:43.7507096Z | ^~~
2026-05-29T18:26:14.2420944Z In function ‘dynamic_user_push’,
2026-05-29T18:26:14.2421730Z inlined from ‘dynamic_user_realize’ at ../src/core/dynamic-user.c:453:13:
2026-05-29T18:26:14.2435240Z ../src/basic/socket-util.h:131:63: error: ‘new_uid_lock_fd’ may be used uninitialized [-Werror=maybe-uninitialized]
2026-05-29T18:26:14.2440497Z 131 | #define send_one_fd_iov(transport_fd, fd, iov, iovlen, flags) send_one_fd_iov_sa(transport_fd, fd, iov, iovlen, NULL, 0, flags)
2026-05-29T18:26:14.2442511Z | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
2026-05-29T18:26:14.2445002Z ../src/core/dynamic-user.c:320:16: note: in expansion of macro ‘send_one_fd_iov’
2026-05-29T18:26:14.2445727Z 320 | return send_one_fd_iov(d->storage_socket[1], lock_fd, &iov, 1, MSG_DONTWAIT);
2026-05-29T18:26:14.2448345Z | ^~~~~~~~~~~~~~~
2026-05-29T18:26:14.2448952Z ../src/core/dynamic-user.c: In function ‘dynamic_user_realize’:
2026-05-29T18:26:14.2451781Z ../src/core/dynamic-user.c:360:21: note: ‘new_uid_lock_fd’ was declared here
2026-05-29T18:26:14.2452287Z 360 | int new_uid_lock_fd;
2026-05-29T18:26:14.2454430Z | ^~~~~~~~~~~~~~~
2026-05-29T18:26:14.2454960Z ../src/core/dynamic-user.c: In function ‘dynamic_user_current’:
2026-05-29T18:26:14.2457632Z ../src/core/dynamic-user.c:468:15: error: ‘uid’ may be used uninitialized [-Werror=maybe-uninitialized]
2026-05-29T18:26:14.2458207Z 468 | uid_t uid;
2026-05-29T18:26:14.2460327Z | ^~~
Daan De Meyer [Tue, 2 Jun 2026 11:51:05 +0000 (11:51 +0000)]
ci: update claude review workflow to opus 4.8
Bump the Bedrock model ID to us.anthropic.claude-opus-4-8 (the -v1 suffix
was dropped after 4.6), pin ANTHROPIC_DEFAULT_OPUS_MODEL so the review
subagents resolve to 4.8 as well, and switch the effort level from max to
xhigh.
Co-developed-by: Claude Opus 4.8 <noreply@anthropic.com>
Luca Boccassi [Tue, 2 Jun 2026 12:15:50 +0000 (13:15 +0100)]
ci: add build/unit-test coverage for armv7 (#42386)
arm64 hosts support running armv7 (armhf) binaries, so we can
cross compile and run the unit tests without performance issues.
armv7 (armhf) is a primary architecture on Ubuntu, so build
regressions block new version updates, and adding coverage
helps to avoid introducing regressions.
elysia090 [Mon, 1 Jun 2026 03:29:58 +0000 (12:29 +0900)]
resolved: process networkd events before RTNL updates
resolved watches networkd state changes and RTNL updates separately. RTNL is
currently processed at SD_EVENT_PRIORITY_IMPORTANT, while networkd state
changes are processed later at SD_EVENT_PRIORITY_IMPORTANT+5.
If both are pending, an RTM_NEWADDR update can make a link relevant for
LLMNR/mDNS scope allocation before resolved has consumed the corresponding
networkd state update. This can let scope recalculation use stale per-link
settings until the networkd event is processed.
Run the networkd monitor source before RTNL by using
SD_EVENT_PRIORITY_IMPORTANT-5. This lets resolved consume current link settings
before reacting to RTNL address updates in the same event loop iteration.
Yu Watanabe [Tue, 2 Jun 2026 05:58:06 +0000 (14:58 +0900)]
libarchive-util: update comment for new library symbols
archive_entry_gid_is_set() and archive_entry_uid_is_set() are added by
https://github.com/libarchive/libarchive/commit/8acb738db6bc7087a5e7cdd328bbfb6e673e5bd8 (3.7.3).
dependabot[bot] [Tue, 2 Jun 2026 04:43:56 +0000 (04:43 +0000)]
build(deps): bump the actions group with 3 updates
Bumps the actions group with 3 updates: [github/codeql-action](https://github.com/github/codeql-action), [aws-actions/configure-aws-credentials](https://github.com/aws-actions/configure-aws-credentials) and [redhat-plumbers-in-action/gather-pull-request-metadata](https://github.com/redhat-plumbers-in-action/gather-pull-request-metadata).
Updates `github/codeql-action` from 4.35.4 to 4.36.0
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](https://github.com/github/codeql-action/compare/68bde559dea0fdcac2102bfdf6230c5f70eb485e...7211b7c8077ea37d8641b6271f6a365a22a5fbfa)
Updates `aws-actions/configure-aws-credentials` from 6.1.1 to 6.1.2
- [Release notes](https://github.com/aws-actions/configure-aws-credentials/releases)
- [Changelog](https://github.com/aws-actions/configure-aws-credentials/blob/main/CHANGELOG.md)
- [Commits](https://github.com/aws-actions/configure-aws-credentials/compare/d979d5b3a71173a29b74b5b88418bfda9437d885...acca2b1b2070338fb9fd1ca27ecee81d687e58e5)
Updates `redhat-plumbers-in-action/gather-pull-request-metadata` from 1.9.1 to 1.10.0
- [Release notes](https://github.com/redhat-plumbers-in-action/gather-pull-request-metadata/releases)
- [Commits](https://github.com/redhat-plumbers-in-action/gather-pull-request-metadata/compare/62fc85c7acd15db62a0bdf007c8dbeda86eaf3b6...ecc2e46fe4f0b2e9a7b236d6012bc9f74af318d0)
Luca Boccassi [Mon, 1 Jun 2026 17:44:52 +0000 (18:44 +0100)]
vmspawn: enforce minimum uptime with --console=gui
When using --console=gui the QEMU window closes immediately when the VM
has stopped, so any console output at shutdown is lost, which makes
debugging difficult. Ensure the VM stays booted for a minimum of 15s.
Luca Boccassi [Sat, 30 May 2026 21:51:59 +0000 (22:51 +0100)]
tree-wide: convert dlopen_*() callers to DLOPEN_* wrapper macros
Switch the executable-owned call sites from the plain dlopen_<lib>()
helpers to the new DLOPEN_<LIB>() macros, so that each binary that loads
an optional library at runtime now carries its own .note.dlopen note
instead of relying solely on libsystemd-shared. Each call site passes a
priority reflecting whether it hard-depends on the library (required) or
degrades gracefully without it (recommended).
Co-developed-by: Claude Opus 4.8 <noreply@anthropic.com>
Luca Boccassi [Sat, 30 May 2026 18:40:51 +0000 (19:40 +0100)]
shutdown: do not delay VM shutdown
Since this was introduced I constantly find myself waiting for VMs to
shut down at the end of a test. This not only happens with mkosi integration
tests, but with other VM-based tests like for example autopkgtest. In this
example, this dracut test suite runtime is tripled due to the artificial delay:
[ 5.813234] systemd-shutdown[1]: Syncing filesystems and block devices.
[ 5.814635] systemd-shutdown[1]: Delaying shutdown for 9s, in order to reach minimum uptime of 15s.
[ 8.816855] systemd-shutdown[1]: Delaying shutdown for 6s, in order to reach minimum uptime of 15s.
[ 11.819747] systemd-shutdown[1]: Delaying shutdown for 3s, in order to reach minimum uptime of 15s.
[ 14.822660] systemd-shutdown[1]: Delaying shutdown for 601ms, in order to reach minimum uptime of 15s.
[ 15.427777] systemd-shutdown[1]: Powering off.
[ 15.429681] sd 0:0:0:0: [sda] Synchronizing SCSI cache
[ 15.433620] ACPI: PM: Preparing to enter system sleep state S5
[ 15.435148] reboot: Power down
TEST: root filesystem on a ext4 filesystem with systemd and extensions [OK]
autopkgtest [19:39:12]: test 46-systemd-sysext: -----------------------]
autopkgtest [19:39:13]: test 46-systemd-sysext: - - - - - - - - - - results - - - - - - - - - -
46-systemd-sysext PASS
Contrary to what the comment claimed, the scrollback of a VM is _not_
cleared, EDK2 just prints many pages, and one can just scroll up (a lot).
Do not delay by default on VMs. Move the check so that in both containers
and VMs users can override and force a delay with the env var.
Luca Boccassi [Sat, 30 May 2026 21:51:17 +0000 (22:51 +0100)]
shared: add DLOPEN_* wrapper macros that stamp .note.dlopen on callers
This macro emits an SD_ELF_NOTE_DLOPEN note so that calling sites,
and not just libsystemd-shared, get the ELF stamped with the notes
documenting the dependency. Currently most of the dlopen notes end
up in libsystemd-shared, and executables have no way to document
the optional dependencies they need. With this new macro, this
issue can be fixed.
Co-developed-by: Claude Opus 4.8 <noreply@anthropic.com>
If the SD_ELF_NOTE_DLOPEN macro gets used twice in the same binary,
with identical content, it will add two identical notes, which is
wasteful and confusing.
Emit each note into a COMDAT group keyed on its JSON payload, with an
assembler .ifndef guard, so byte-identical notes fold to a single copy
within a translation unit (assembler) and across translation units
(linker). The section is marked SHF_GNU_RETAIN so --gc-sections keeps it,
and uses the portable "%note" section type so it also assembles on
architectures where "@" is the comment character (e.g. 32-bit ARM).
This ensures SD_ELF_NOTE_DLOPEN can be used as many times as needed,
and the result will be automatically deduplicated.
The SHF_GNU_RETAIN (R) flag requires binutils >= 2.36, which cuts
off CentOS 9. To avoid breaking builds, override the flags passed
to the linker to skip that flag. This unfortunately means in many
cases the ELF notes section will be dropped by the linker due to
--gc-sections. For CentOS 9 builds, the choice is thus between
not using --gc-sections and losing dlopen ELF notes, and the latter
is made here given it's less impactful.
Co-developed-by: Claude Opus 4.8 <noreply@anthropic.com>
Luca Boccassi [Mon, 1 Jun 2026 16:38:28 +0000 (17:38 +0100)]
systemd-tmpfiles: remove age-based cleanup of X11 socket directories (#42358)
Unexpected cleanup of live X11 socket files was reported in #35182,
suggesting an underlying issue with the `!` boot safety switch for
tmpfiles.
Regardless of that bug, time-based cleanup of X11 sockets is likely to
be unwanted behaviour as systems often stay up for extended periods of
time, and cleanup of these directories based on age alone is liable to
cause issues at runtime for user sessions.
Luca Boccassi [Mon, 1 Jun 2026 11:15:52 +0000 (12:15 +0100)]
Translations update from Fedora Weblate (#42417)
Translations update from [Fedora
Weblate](https://translate.fedoraproject.org) for
[systemd/main](https://translate.fedoraproject.org/projects/systemd/main/).
manager: if called with compat telinit interface, tell users to update
In https://bugzilla.redhat.com/show_bug.cgi?id=2479961 a user
reported that they are confused that 'init 6' and such commands
do not work anymore. We removed support for the whole interface,
but it's likely that such commands persist in various scripts
and finger memories. Let's give a helpful hint that this inteface
is gone and what to use instead.
We shouldn't say that that they boot into "a … legacy target", because
they boot into the standard targets. Those names are just aliases now.
(And also the user is not required to know what SysV even is, so it
shouldn't be used in the main explanation.)
Luca Boccassi [Mon, 1 Jun 2026 09:09:43 +0000 (10:09 +0100)]
docs: specifically mention that braces in if blocks do not need to be symmetric
The claude bot keeps getting this wrong again and again:
Claude: nit: systemd coding style requires braces on both branches of
an if/else when one branch uses them. Here the if branch
is a single statement without braces but the else branch
uses braces
Specifically mention this is not the case in the coding style doc
to hopefully make it stop hallucinating this rule
Luca Boccassi [Sun, 31 May 2026 16:38:40 +0000 (17:38 +0100)]
test: make TEST-60-MOUNT-RATELIMIT more robust
TEST-60-MOUNT-RATELIMIT sometimes fails as it cannot see the 'left rate limit'
message in the journal. Tests relying on specific log messages are often flaky,
as the journal is lossy.
Change the test case to check for the desired outcome instead, as that also
catches regressions, without being over reliant on the journal.
Luca Boccassi [Sun, 31 May 2026 11:44:14 +0000 (12:44 +0100)]
journalctl: don't assert on MESSAGE field without "MESSAGE=" prefix
sd_journal_get_data() can return a MESSAGE data object whose payload does
not start with "MESSAGE=", e.g. when the journal file is corrupted. Instead
of aborting the whole process, log and skip over such an entry like we do for
other bad/missing fields.
Luca Boccassi [Sun, 31 May 2026 10:55:15 +0000 (11:55 +0100)]
Translations update from Fedora Weblate (#42403)
Translations update from [Fedora
Weblate](https://translate.fedoraproject.org) for
[systemd/main](https://translate.fedoraproject.org/projects/systemd/main/).
Currently translated at 100.0% (285 of 285 strings)
Co-authored-by: Fco. Javier F. Serrador <fserrador@gmail.com>
Translate-URL: https://translate.fedoraproject.org/projects/systemd/main/es/
Translation: systemd/main
tmpfiles: exclude x11 lock files from time-based cleanup
We need a removal rule for systems where /tmp is not on tmpfs,
so that if they crash, stale sockets will be removed during boot.
OTOH, at runtime, those lock files must never be removed.
But since the 'r!' rule uses '!', it only applies during boot. With
the rule inactive, the usual time-based cleanup for /tmp/ was also
applied to those files, causing them to be removed after 10 days.
tmpfiles: remove boot-only restriction from x11 directory rules
4a1f92c704aad80e9fde3f3d1678a5e5e944ae47 added '!' through confusion:
the goal was probably to exclude those directories from cleanup at
runtime. But as discussed below, that exclusion is not needed. In fact,
we want the rule to be active during runtime, so that if the directory
were removed or wasn't created earlier for whatever reason, it'd be
created during one of those later runs too. This just makes the system
more robust.
Those directories are used for sockets, and tmpfiles will not remove
live sockets. So it is fine to run the cleanup on those directories,
it doesn't have any effect in normal circumstances. The only case where
the cleanup would matter would be if the service was running, crashed
without removing the socket, and the system would remain up for more
than 10 days after that. This is not a particularly likely scenario, but
OTOH, we can imaging that somebody tried to run Xorg, it didn't work,
and they switched to Wayland. Or their DE crashes every once in a while,
leaving some state behind. Keeping the cleanup in place seems OK, it
makes the system slightly more robust in fringe scenarios.
In fact, this cleanup will work better if we reduce the delay from
10 days to something small. systemd-tmpfiles-clean.timer runs once
per day, so the cleanup will not be very fast anyway. So use '1h' as
an arbitrary small value. (I think '0' would be risky, because it's
possible for the socket to be set up through a script where it's
created first and the service is connected to it, so it is momentarily
"not live". I think people used to do this. Not sure if that happens
anymore, but let's be safe.)
Luca Boccassi [Fri, 29 May 2026 12:42:24 +0000 (13:42 +0100)]
ci: add build/unit-test coverage for armv7
arm64 hosts support running armv7 (armhf) binaries, so we can
cross compile and run the unit tests without performance issues.
armv7 (armhf) is a primary architecture on Ubuntu, so build
regressions block new version updates, and adding coverage
helps to avoid introducing regressions.
Luca Boccassi [Fri, 29 May 2026 11:37:31 +0000 (12:37 +0100)]
hwdb: reject overlong fnmatch key instead of passing NULL to fnmatch()
When the accumulated trie key exceeds the fixed-size line buffer,
linebuf_get() returns NULL. trie_fnmatch_f() passed that NULL straight
into fnmatch() as the pattern, causing a SIGSEGV on a crafted hwdb.bin
(reachable now that recursion is capped rather than overflowing the
stack first). Treat the NULL like the other corruption checks and
return -EBADMSG.
Daan De Meyer [Fri, 29 May 2026 07:16:33 +0000 (07:16 +0000)]
ssh-proxy: Default to root user
When ssh-ing into a VM, you generally do not want to log
in as your user from the host. Let's default to the root
user unless a user is explicitly specified.
Daan De Meyer [Thu, 28 May 2026 09:26:05 +0000 (09:26 +0000)]
ssh-generator: Make sure sshd can always read the authorized keys file
sshd reads AuthorizedKeysFile after dropping to the authenticating user's UID, so the
0400 credential file under %d/ is unreadable for non-root users. Materialize a 0444
copy in a RuntimeDirectory so the ephemeral key works for any user. */
Yu Watanabe [Thu, 28 May 2026 16:12:29 +0000 (01:12 +0900)]
units: drop Before=sockets.target from networkd resolve hook
Otherwise, it introduces cyclic dependencies:
```
systemd[1]: sockets.target: Found ordering cycle:
systemd-networkd-resolve-hook.socket/start after network-pre.target/start after
iptables.service/start after basic.target/start after sockets.target/start -
after systemd-networkd-resolve-hook.socket
systemd[1]: sockets.target: Job systemd-networkd-resolve-hook.socket/start deleted
to break ordering cycle starting with sockets.target/start
```
jeffhuang [Wed, 27 May 2026 18:08:38 +0000 (18:08 +0000)]
pe-binary: bound section data against file size, cap UKI zero-padding hash, validate optional header size
A hostile but structurally valid 382-byte PE32+ "EFI application" with a
single section whose VirtualSize is ~4 GiB and SizeOfRawData is 0 drives
uki_hash() into ~4.17 M iterations of SHA-256 over 1024 bytes of zeros
— wedging the parser for >10 s. Nine more slow-units share the same
shape. A separate MSAN finding from the new fuzzer (CIFuzz, memory
sanitizer) shows pe_load_headers() reading uninitialised heap memory
when SizeOfOptionalHeader is too small to actually contain
NumberOfRvaAndSizes.
Three tightenings in src/shared/pe-binary.c:
1. In pe_load_sections, reject sections whose PointerToRawData +
SizeOfRawData exceeds the actual file size. Raw section data must
fit inside the file; this is the parser-wide invariant
pe_hash / uki_hash / pe_read_section_data rely on.
2. In uki_hash, cap the (VirtualSize - SizeOfRawData) zero-padding
hash loop at 64 MiB. Real UKIs do not pad sections with tens of
MiB of zero-equivalent data; anything above this cap is a
malformed PE.
3. In pe_load_headers, reject a PE whose SizeOfOptionalHeader is too
small to cover up to NumberOfRvaAndSizes. Without this guard the
subsequent size-mismatch check reads uninitialised optional-header
bytes, caught by MSAN under CIFuzz.
Add the 382 B canonical reproducer (plus two structural siblings) and
the MSAN reproducer to test/fuzz/fuzz-pe-binary/. Also add a libFuzzer
harness in src/fuzz/fuzz-pe-binary.c and unit tests in
src/test/test-pe-binary.c that exercise each fix branch in isolation.
The 64 MiB hash boundary test is gated behind SYSTEMD_SLOW_TESTS so it
doesn't slow down emulated-arch CI.
This is a robustness fix, not a security fix: PE binaries consumed by
bootctl / systemd-stub / pcrlock / kernel-install / systemd-measure are
already trusted and signed at the consumer side, so the worst pre-fix
behaviour is wasted CPU on a UKI install / measure / inspect call.
Closes #42344.
Reported-by: AI-assisted libFuzzer campaign Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
We currently log at warning level:
/usr/lib/systemd/system/systemd-udevd.service:56: System call bpf cannot be
resolved as libseccomp is not available, ignoring: Operation not supported
In the initrd, or in minimal installations, not installing libseccomp is
reasonable, depending on various other choices. We shouldn't make fuss
about this.
profile.d: add instructions how to deactivate 80-systemd-osc-context.sh
This was requested in https://github.com/systemd/systemd/issues/42333.
Indeed, this integration is using three levels of systemd magick, so
doing this correctly is not obvious. Let's include specific instructions
to help people for whom this integration is causing problems.
fd-util: add wildcard_fd_is_valid() helper and use it tree-wide
Many *at()-style helpers accept a directory fd that may be either a
regular, valid fd (>= 0) or one of the special AT_FDCWD/XAT_FDROOT
wildcard values, and open-code that check in their assertions. Add a
wildcard_fd_is_valid() helper for it and use it tree-wide.