Commit Graph

90447 Commits

Author SHA1 Message Date
dongshengyuan
8cbae52fc9 pcrlock: handle piped PE input
When lock-pe or lock-uki read from stdin,
copy non-regular input to a seekable temporary fd before hashing it.

Fixes #42893.
Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
2026-07-09 11:02:46 +02:00
dongshengyuan
4839cb914e dissect: do not follow copy-to directory symlinks
When copying a directory into an image, open an existing destination
with O_NOFOLLOW before passing it to copy_tree_at(). This rejects a
symlink used as the final destination component without a separate
stat-before-use check.

Previously the pre-opened destination followed that symlink. That
allowed --copy-to to be redirected outside the image root when the
image was a directory tree.

If the destination does not exist yet, keep delegating creation to
copy_tree_at(). Real existing directories still use COPY_MERGE through
the opened directory fd.

Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
2026-07-09 11:01:29 +02:00
Lennart Poettering
04915e3d37 Assorted coverity fixes (#42933) 2026-07-09 11:01:03 +02:00
Lennart Poettering
af8700527a shared: fix DNS RR wire cache and EFI boot option bounds checks (#42926)
Invalidate cached DNS RR wire format when
`dns_resource_record_clamp_ttl()` updates `rr->ttl` in place.
Validate each EFI `Boot####` device-path node length before reading
subtype-specific fields.
2026-07-09 11:00:29 +02:00
Lennart Poettering
5f44e242ae Assorted journal/portable hardening fixes flagged by kres (#42915) 2026-07-09 10:59:02 +02:00
Lennart Poettering
76c697f1fb journal-remote: do not create /var/log/journal/remote (#42937)
This handling with tmpfiles was dropped in
29444df23b. So let's stop the build system
to create that directory. Actually it is create by the service just
fine, including correct access mode.
2026-07-09 10:55:13 +02:00
Kai Lüke
2f76050c5c stub: Prefer graphical console over virtio detection heuristic
With vmspawn --console=gui and similar one has the case where the VirtIO
PCI device is present for something else than the console and the logic
in sd-stub added console=hvc0 even though it didn't exist. This caused
tty0 to be empty during boot.
Always prefer the graphical console before a potential virtio console.
The virtio console is still preferred over a serial console and we can
get the same problem there, e.g., qemu-guest-agent is used causing the
PCI device but without a virtio console and instead a serial console is
used. This is not solved here.
2026-07-09 10:54:52 +02:00
countgitmick
ce043cdfdb logind: set session->started before seat_read_active_vt() call
session_start() calls seat_read_active_vt() before setting
s->started = true. seat_read_active_vt() can reach
seat_triggered_uevents_done() synchronously via:

  seat_active_vt_changed -> seat_set_active -> seat_trigger_devices
  -> seat_triggered_uevents_done

When seat_trigger_devices() produces no pending uevents,
seat_triggered_uevents_done() runs in the same call stack as
session_start() and tests session->started before the assignment
further down. The check fails, session_device_resume_all() is
skipped, and the compositor never receives DRM master.

Set started before seat_read_active_vt() so the gate sees the
correct value, and document the ordering constraint at the call
site to prevent regression.

Reproducible with greetd plus a Wayland compositor on the same VT
on kernel 6.19+.

Fixes: #41562
Signed-off-by: countgitmick <263313427+countgitmick@users.noreply.github.com>
2026-07-09 10:17:46 +02:00
Christian Hesse
fc99dc4c42 journal-remote: do not create /var/log/journal/remote
This handling with tmpfiles was dropped in
29444df23b. So let's stop the build system
to create that directory. Actually it is create by the service just
fine, including correct access mode.
2026-07-09 09:09:34 +02:00
Christian Hesse
7e9af6ba05 mkosi: update arch commit reference to f884cb080300eeb273fb7549fd0aa19bb6142c21 2026-07-09 09:09:34 +02:00
dongshengyuan
d13b002aec efi-api: validate boot option device path lengths
efi_get_boot_option() validates the overall Boot#### variable size and
the advertised device-path byte count, but then walks each device-path
node without first checking that the node header and subtype payload fit
in the remaining buffer.

A malformed Boot#### variable could make the parser read past the end of
the current node, or past the available device-path data.

Limit parsing to the bytes that are actually present, and stop walking
the device path when a malformed node is encountered. This keeps the
previous best-effort behaviour for fields parsed before the anomaly while
avoiding out-of-bounds reads.

Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
2026-07-09 08:39:03 +08:00
dongshengyuan
ccae5c7a4f dns-rr: invalidate wire format after changing ttl
dns_resource_record_clamp_ttl() may patch the TTL in place when the
record has a single reference. dnssec_fix_rrset_ttl() also updates TTLs
after canonical wire-format data may have been cached.

If a record already has cached wire-format data, that cache still
contains the old TTL and dns_resource_record_to_wire_format() will keep
reusing it.

Add a small helper to clear the cached wire-format state, and use it
whenever the TTL changes. This makes subsequent serialization match the
record fields.

Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
2026-07-09 08:35:03 +08:00
Andres Beltran
001c5dfdf5 tmpfiles: add hardening in glob_item_recursively 2026-07-08 22:50:55 +01:00
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
Luca Boccassi
052ff5fb5d resolved: honour per-link DNSOverTLS=yes for certificate verification
dnstls_stream_connect_tls() reads the manager-wide dns_over_tls_mode
field directly, so when the global mode was 'no' or 'opportunistic' but
a link was configured with strict DNSOverTLS=yes, the DoT connection
was established without SSL_VERIFY_PEER or hostname/IP checks.
Use dns_server_get_dns_over_tls_mode() which honours the per-link
override.
2026-07-08 17:29:03 +02:00
Luca Boccassi
feda6f31d8 pcrlock: add vl method for list-components
Add varlink method wrapper for list-components verb.
2026-07-08 16:22:05 +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
Lương Việt Hoàng
0168b13fb3 creds-util: log when we remove a secret from a different machine 2026-07-08 14:49:14 +01:00
Luca Boccassi
7967b6b6d5 sd-device: check fd validity before using in sendmsg in test
CID#1663676

Follow-up for 7003a9bf09
2026-07-08 13:36:32 +01:00
dongshengyuan
34a2223344 dns-rr: fix SOA JSON fields
Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
2026-07-08 13:03:23 +01:00
dongshengyuan
da9a330dfd fsck: don't apply invalid mode or repair values
fsck_mode_from_string() and fsck_repair_from_string() return -EINVAL
on a bad value. Store the result in a local variable first, and only
update the global state on success.

Otherwise an invalid value is logged as ignored, but still leaves a
negative enum value behind. In the fsck.repair case that makes
fsck_repair_option_to_string() return NULL and truncates the fsck
command line.

Follow-up for a85428b1d3
Follow-up for 059afcadfd

Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
2026-07-08 12:13:43 +01:00
Elliot Berman
1b03303998 bootctl: Fix prepend when installing systemd-boot for the first time
In commit 38433a6d06 ("bootctl: rework bootctl-install.c in preparation of varlinkification"),
the `first` argument of install_boot_option() was reworked to use the
new InstallContext struct/InstallOperation. `first` was intended to
indicate if we were on the install path, so the check should be
== INSTALL_NEW, not != INSTALL_NEW.

Fixes: 38433a6d06 ("bootctl: rework bootctl-install.c in preparation of varlinkification")
2026-07-08 11:06:42 +01:00
Luca Boccassi
6248f1b774 sd-bus: voidify bus_match_remove call
It cannot fail, just returns 0 or 1 for not found/found

CID#1663675
2026-07-08 10:54:04 +01:00
Syed Mohammed Nayyar
636b173035 measure-smbios: bound type 1 length before zeroing wake-up type
The structure length comes from the firmware SMBIOS table and the only
bound before the fixed-offset wake_up_type write was an assert(), which
is a no-op in release sd-boot builds.

Whether the field is present is governed by the formatted-area length
header->length, not the total size which also covers the trailing string
set. A too-short record (an old SMBIOS 2.0 one, or a crafted 6-byte
header) makes the offset-24 write land past the xmemdup() copy; a record
with a short formatted area but long string set instead gets a stable
string byte zeroed in the copy. Key the guard off header->length and the
field offset, matching get_smbios_table(), and measure such records
as-is. Zero only the part of the field that lies within the formatted
area, and collapse the two measure_smbios_raw() call sites by selecting
what to measure via a pointer.

Signed-off-by: Syed Mohammed Nayyar <jmestwa@gmail.com>
2026-07-08 08:33:47 +02:00
Lars Sjöstrom
231fddc337 core: support stdio fd passing in io.systemd.Unit.StartTransient
Add StandardInputFileDescriptor, StandardOutputFileDescriptor and
StandardErrorFileDescriptor to the Service context of the Varlink
StartTransient() method. Each carries the push-order index of a file descriptor
passed along with the method call (via SCM_RIGHTS), and connects it to the
transient service's standard input/output/error. This is the Varlink equivalent
of the StandardInputFileDescriptor= / StandardOutputFileDescriptor= /
StandardErrorFileDescriptor= D-Bus transient properties behind
"systemd-run --pipe", which had no Varlink counterpart.

The manager Varlink server now enables SD_VARLINK_SERVER_ALLOW_FD_PASSING_INPUT
so clients may attach descriptors to their method calls, matching other
fd-accepting Varlink services (mountfsd, networkd, vmspawn, ...). The indices are
resolved with sd_varlink_peek_dup_fd() after the polkit authorization check and
stored on the Service exactly like the D-Bus path
(bus_set_transient_exec_context_fd()): the fds land in stdin_fd/stdout_fd/
stderr_fd and exec_context.stdio_as_fds is set, so the existing exec-invoke
plumbing wires them to the spawned process unchanged. Unsuitable fds (bad
index, wrong access mode) are rejected as InvalidParameter, other resolution
failures propagate as raw errnos.

Add coverage to TEST-74-AUX-UTILS.varlinkctl-unit.sh, passing regular files as
the stdout/stderr fds and asserting the unit's output lands on them.
2026-07-08 08:31:29 +02:00
Julian Sparber
d9c0d7974e sysinstall: Disable timeout for connection with repart
The repart connection was timeing out when fetching candidate devices.
Therfore disable the timeout and keep the connection open till the user
disconnects.
2026-07-08 08:27:13 +02:00
Paul Meyer
626161a24c gitignore: add .envrc, .direnv
Signed-off-by: Paul Meyer <katexochen0@gmail.com>
2026-07-08 08:23:04 +02:00
Zbigniew Jędrzejewski-Szmek
6b325a3613 Adjust naming of meson variables and allow systemd-report* binaries to be built standalone (#42874) 2026-07-07 21:35:41 +02:00
Luca Boccassi
c70f09853e portable: fix marker_matches_images() and propagate errors correctly
marker_matches_images() was declared to return bool, but several of its
paths return a negative errno (OOM, parse errors, etc.). A negative int
coerces to true, so every such failure was reported as a "match".

Return int with the tristate semantics the callers already expect.

When detaching by image name instead of the original path, path_pick() may
not resolve a concrete path (e.g. a runtime overlay). Keep comparing the
caller-provided image name, and use the picked path only as an additional
canonical match when it exists.

Follow-up for 907952bbc9
2026-07-07 18:03:00 +01:00
Luca Boccassi
a77bd724d3 journald: replace existing syslog event source before reopening
manager_open_syslog_socket() may be called again with an already open
syslog fd. In that case the old syslog event source still watches the
fd, so adding a new IO source for the same fd fails with -EEXIST and
leaves the old source installed.

Disable and unref the old event source before adding the replacement.
This keeps reopening idempotent and avoids leaving a stale event source
around.

Follow-up for f9a810beda
2026-07-07 18:01:50 +01:00
Luca Boccassi
0b4a90765c journald: pin the sending client's context across native message dispatch
manager_process_native_message() looks up the sender's ClientContext with
client_context_get(), which does not pin it.

A native message may carry an OBJECT_PID=, which makes
manager_dispatch_message_real() perform a nested client_context_get() for that
PID. On a cache miss this runs client_context_try_shrink_to(), whose pid-flush
branch frees every unpinned cache entry whose PID has already been reaped,
including the borrowed sender context. manager_dispatch_message_real() then keeps
using it (it reads c->uid, and the built iovecs still alias the context's
fields).

Pin the sender context with client_context_acquire() for the duration of the
dispatch and release it afterwards, mirroring what the stdout stream path
already does.

Follow-up for 22e3a02b9d
2026-07-07 18:01:50 +01:00
dongshengyuan
a977bf4d06 portable: detect drop-in-only attachments
Commit edea370222 (portable: remove drop-in configs even if the main unit file does not exist)
taught detach to handle leftover .service.d directories
after the main unit symlink was removed.

portable_get_state_internal() still had the same blind
spot: it only considered regular unit entries, so portablectl
is-attached could report detached while a portable drop-in directory was still present.

Handle those drop-in-only entries like detach does, preserve
the existing unit-file based enabled checks when the
main unit file is still present, and add TEST-29 coverage.

Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
2026-07-07 18:47:30 +02:00
Vsevolod Kozlov
93aadbf968 sbsign: write unaligned signature size into WIN_CERTIFICATE header
The inclusion of padding bytes in the signature size can lead to the signature
being rejected by strict PKCS7 parsers. Meanwhile, according to [1], the parser
of the WIN_CERTIFICATE structure is expected to round up the value of dwLength
to an 8-byte multiple. This also matches the behaviour of the sbsign tool from
sbsigntools.

Fixes #42884

[1] https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#the-attribute-certificate-table-image-only

Signed-off-by: Vsevolod Kozlov <zaba@mm.st>
2026-07-07 18:45:14 +02:00
dongshengyuan
d8c1f1d105 pull: honor sync for OCI artifacts
Synchronize OCI layer directories and generated metadata
when IMPORT_SYNC is enabled, matching the raw and tar pull paths.

Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
2026-07-07 18:43:42 +02:00
dongshengyuan
366fa466d2 copy: keep replaced target after publish errors
Once link_tmpfile_at() succeeds, the target path
has been published. Avoid unlinking it on later
close or parent fsync failures when COPY_REPLACE
was used, as that can remove the replaced target.

Signed-off-by: dongshengyuan <dongshengyuan@uniontech.com>
2026-07-07 18:41:26 +02:00
Zbigniew Jędrzejewski-Szmek
e785d81c1b mkosi: update fedora commit reference to 57cbcf979ce2dd872a871c59e87d2c65dfa996e6
* 57cbcf979c Also enable report-standalone for OBS builds
* d69c17b165 Enable report-standalone for upstream builds
2026-07-07 18:37:12 +02:00
Zbigniew Jędrzejewski-Szmek
f731334d84 meson: use modern syntax for dict checks 2026-07-07 13:40:13 +02:00
Zbigniew Jędrzejewski-Szmek
9155c0a5b9 meson: build .standalone versions of the report binaries
The goal is to be allow the use of those binaries on systemd with older
systemd. The report stuff is generally independent of the running systemd
version.

When built with -Dinstall-tests=true -Dstandalone-binaries=true
-Dbuildtype=release -Db_lto=true, gcc-16.1.1-2.fc44.x86_64, the sizes
are quite reasonable:

$ ls -lG build-lto/*.standalone
-rwxr-xr-x 1 zbyszek  713200 Jul  3 13:16 build-lto/systemd-report.standalone
-rwxr-xr-x 1 zbyszek  662936 Jul  3 13:16 build-lto/systemd-report-basic.standalone
-rwxr-xr-x 1 zbyszek  567424 Jul  3 13:16 build-lto/systemd-report-cgroup.standalone
-rwxr-xr-x 1 zbyszek  592856 Jul  3 13:16 build-lto/systemd-report-files.standalone
-rwxr-xr-x 1 zbyszek  589864 Jul  3 13:16 build-lto/systemd-report-sign-plain.standalone
-rwxr-xr-x 1 zbyszek  548624 Jul  3 13:16 build-lto/systemd-report-sign-tsm.standalone
2026-07-07 13:40:13 +02:00
Zbigniew Jędrzejewski-Szmek
aad1e61010 meson: adjust naming of '*extract*' variables 2026-07-07 13:40:13 +02:00
Zbigniew Jędrzejewski-Szmek
f00ccf93b7 meson: rename extract+objects to export+import
We have two concepts: a list of files that should be extracted from an
intermediate build artifact to be used in a later build artifact, and for a
given artifact, a list "donors". The first list was called "extract", because
it is passed to the .extract_objects() meson function, and the second was
called "objects", because that is the meson parameter to specify pre-built
objects files (6350d2dbd9). But this naming is
confusing: we don't care about the 'extract' step, this is something internal
to the build machinery. And 'objects' is a very generic term.

Let's use 'export' for the stuff that is "exported" for other binaries to use,
and 'import' to say where to import from. Those terms are symmetrical and the
association between them should be intuitive. (If you think the terms are
actually assymetrical, there are precedents for confusing the import with the
import sources. E.g. in modern English, turkeys are called so because they were
imported from the Americas and guineafowls were imported from Africa via
Türkiye and all that foreign stuff is alike.)
2026-07-07 13:40:13 +02:00
Zbigniew Jędrzejewski-Szmek
88b51ff974 meson: move 'conditions' to the end 2026-07-07 13:40:13 +02:00
Zbigniew Jędrzejewski-Szmek
47af1efe40 mkosi: update fedora commit reference to 45c16dd369c961b70664e473552def34d5469664
* 45c16dd369 Use uniform format for %rhel conditionals
* 034fa693f2 Print the build status also in %build
* 3cc7e03365 Restore definitions of helper macros
* 2382c910b7 Disable the standalone report yet again
* 2d6fd95c70 Restore explicit requires for Centos Stream 9 and 10
* 521ab0fb09 test: skip the integration test suite on Fedora ELN (for now)
* 453447b79b rpminspect: ignore test-coredump-stacktrace in annocheck
* 9d4edaa576 test: work around a kernel bug in virtio/vsock
* c53b2fb307 test: cap the number of parallel tests
* 9bd26bb71f Fix ntpvendor for ELN
* de7b685908 Disable reqs for dlopen'ed libraries on CentOS
* 4830641844 Move portabled to systemd-container subpackage
* 893fcd9978 Add missing conditionalization and more debugging
* c783e74791 split-files: improve error message
* ee2dff42d6 Add systemd-report-standalone
* 9c87a3f8ad Load libssl.so.4 rather than libssl.so.3
* 714b0799d2 Version 261.1
* 054158500a Update to load openssl-4 rather than openssl-3
* 5a3e750ef8 Version 261
* 4faee7ab7d Version 261~rc4
* 8ff635a921 Rebuilt for openssl 4.0
* 0064f73d97 Rebuilt for openssl 4.0
* 14a9aac87e Use dlopen notes again
* 720fa8259a Do not check ownership of /var/lib/systemd/timesync/ in rpm -V
* 06bd9926f2 Version 261~rc3
* 6ddbd499e8 Drop unused tree build dependency
* bd81a14bfc Version 261~rc2
2026-07-07 12:33:48 +01:00
Zbigniew Jędrzejewski-Szmek
e20ab6642c Assorted libsystemd/network hardening fixes flagged by kres (#42865) 2026-07-07 13:27:57 +02:00
Matthew Schwartz
5f6ad50d20 hwdb: add MSI Claw 8 EX AI+ CG3EM to keyboard hwdb list 2026-07-07 09:51:27 +01:00
Michael Vogt
6bfd3424e8 journalctl: add follow mode to the varlink method
This commit implements `journalctl -f` like behavior for the
varlink API of journalctl. It is used via:
```
$ varlinkctl call -E \
    /run/systemd/io.systemd.JournalAccess \
    io.systemd.JournalAccess.GetEntries '{"follow": true, "limit": 10}'
```
This gives the last 10 message and then it keeps the connection
open and output each new log line that matches the set filters.

The code is modeled after `journalctl -f`. It seems there is little
to extract into shared code here so I left it for now.
2026-07-07 09:45:03 +02:00
Lennart Poettering
7ab48accb2 vmspawn: discover firmware descriptors, opt-in secure boot support for coco (#42876) 2026-07-07 08:55:10 +02:00
Luca Boccassi
46c15e88e0 resolve: anchor the service browser from mDNS maintenance queries
mdns_maintenance_query() takes a ref on the browser's varlink link but
never installs itself as that link's userdata. dns_query_free() then
unconditionally runs sd_varlink_set_userdata(varlink_request, NULL),
so freeing any maintenance query wipes the browse query's registration
on the shared sb->link slot, disabling the abort paths in
vl_on_disconnect() and dns_service_browser_free(). The maintenance
query also never takes a reference on the DnsServiceBrowser, so a client
disconnect could free the browser while a maintenance query was still
in flight, leaving the per-service schedule_event timer and the raw
service->service_browser back-pointer dangling (use-after-free on the
next timer tick or query completion).

Take a service_browser_request reference instead, matching the browse
query path. dns_query_free() already drops it. The browser now outlives
its in-flight maintenance queries.

Follow-up for 8458b7fb91
2026-07-06 13:42:22 +01:00
Luca Boccassi
134df27257 network: implement refcounting for SR-IOV objects
link_request_sr_iov_vfs() queued each request with a raw SRIOV* as
userdata and a NULL free_func, so the request did not own the object.
The SRIOV is owned by link->network->sr_iov_by_section, which is freed
by network_free() on reload while the RTM_SETLINK reply may still be in
flight (the floating netlink slot keeps the request alive but does not
keep the userdata alive). A later reply, or the 25s netlink timeout,
then dispatches sr_iov_handler() which reads the freed SRIOV.

Follow-up for cb8453cc51
2026-07-06 13:42:22 +01:00
Luca Boccassi
7eb7d46f97 udev: clear event back-pointer when freeing a worker
worker_free() did not clear worker->event->worker, leaving an event
that was still attached to a worker pointing at freed memory once the
worker was gone. manager_free() frees the workers (hashmap_free())
before it walks manager->events to process them, and event_free() then
writes event->worker->event = NULL into the already-freed worker.

Clear the back-pointer in worker_free(), mirroring event_free() which
already clears the worker's pointer. The link used to be torn down by
the event_free(worker->event) call in worker_free(), which was dropped
when events became reference counted.

The Event and Worker definitions move to udev-manager.h (next to
Manager) so the unit test can construct and free a bound worker/event
pair.

Follow-up for cb16d47f30
2026-07-06 13:42:22 +01:00
Luca Boccassi
b7b1303209 sd-bus: drop half-registered vtable members on failure
add_object_vtable_internal() inserts BusVTableMember entries into the
global vtable_methods/vtable_properties sets as it walks the vtable, but
only sets node_vtable.node (which gates the disconnect-time cleanup)
after the loop. A failure mid-loop thus left the already-inserted
members behind, dangling once the slot's interface string and the node's
path were freed, so a later registration reading those keys hit a
use-after-free. Remove this slot's members on the fail path.

The test asserts the failed registration leaves no member behind.

Follow-up for 19befb2d5f
2026-07-06 13:42:22 +01:00