Commit Graph
2928 Commits
Author SHA1 Message Date
Daan De MeyerandLuca Boccassi 3978b076af loop-util: shortcut block device fd when it carries no partition table
663f0bf5cb stopped reusing the original block device fd whenever
partition scanning was requested (LO_FLAGS_PARTSCAN) but couldn't be
enabled on the device, so that nested partition tables on devices the
kernel won't scan (e.g. the pmOS/android case) get exposed via a real
loop device.

However that also forced a pointless loop device for any partition that
carries a file system directly, e.g. a btrfs subvolume mounted via
MountImages=. For multi-device btrfs this is fatal: the kernel rejects
seeing the same member via both the original partition and the loop
device, and the mount fails.

A loop device is only ever needed here to expose a nested partition
table. So only refuse the shortcut when the device actually carries one,
probed via gpt_probe(), instead of whenever partition scanning is
disabled. Devices carrying a file system directly (or nothing) take the
shortcut as before.

Add an integration test to cover the failure scenario of the original
issue.

Fixes: https://github.com/systemd/systemd/issues/42520
Replaces: https://github.com/systemd/systemd/pull/42576
Follow-up for 663f0bf5cb79ecaf6dd71441ecdc9dc401e7eae6

Co-Authored-By: Luca Boccassi <luca.boccassi@gmail.com>
Co-developed-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-16 00:16:05 +01:00
Luca Boccassi 11bc593c68 sysupdate: reject short manifest hashes
unhexmem_full() ignores whitespace, so a 64-byte manifest digest field
can decode to fewer than 32 bytes. Reject that while parsing instead.

[   83.883087] TEST-72-SYSUPDATE.sh[5995]: systemd-sysupdate: ../src/src/sysupdate/sysupdate-resource.c:581: resource_load_from_web: Assertion `h.iov_len == sizeof(instance->metadata.sha256sum)' failed.

Follow-up for 43cc7a3ef4

Assisted-by: kres (claude-opus-4-7)
Co-developed-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-15 06:59:24 +09:00
Luca Boccassi 92e4afc4d3 ask-password: do not reuse flags across Varlink calls
The flags parameter is parsed into a global variable, which means
when there are multiple consecutive calls it is reused. Switch to
a local copy.

Follow-up for 066f6bfb62

Assisted-by: kres (claude-opus-4-7)
Co-developed-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-13 09:39:28 +01:00
Nick Rosbrook 55ba38cefc test: fix check for updatectl
The have_updatectl variable is meant to gracefully handle the case where
updatectl is missing. But, because the script runs with -e, it fails
immediately in that case instead. Moreover, expanding $have_updatectl
when it is present actually executes updatectl, rather than simply
checking for its existence.

Re-factor this check so that it does handle a missing updatectl.
2026-06-11 15:17:36 +01:00
Luca Boccassi 5d31694318 journal-importer: cap field size when checking
Originally reported on yeswehack.com as YWH-PGM9780-82

Follow-up for 1e448731f5
2026-06-07 21:49:43 +02:00
Yu Watanabe a54c100a1d TEST-58-REPART: support libdevmapper built without UDEV_SYNC_SUPPORT
When libdevmapper is built without UDEV_SYNC_SUPPORT (e.g. on Alpine/postmarketOS),
it creates a device node under /dev/mapper/ instead of relying on udev to create a symlink.
2026-06-05 07:23:34 +09:00
Yu Watanabe 76407b6939 TEST-46-HOMED: postmarketos does not have homed
Hence, the distro check in the test case is not necessary, at least now.
2026-06-05 07:23:34 +09:00
Yu Watanabe a0a1158352 TEST-13-NSPAWN: /proc/kcore may not exist
Similar to 45014d97dd.
Follow-up for 83b8daa032.
2026-06-05 04:56:34 +09:00
Yu Watanabe a576bc9a27 TEST-13-NSPAWN: explicitly create usr/lib/systemd directory in the container image
The main systemd package is not installed in the minimal image,
hence the directory may not exist.
2026-06-05 04:56:34 +09:00
Yu Watanabe 421429e7fe test: replace 'grep -q' with 'grep >/dev/null'
After afa3eb821d, we have introduced 'grep -q'
at several places. Let's replace them.
2026-06-05 04:56:34 +09:00
Yu Watanabe 8cfe1c2f7e test: skip test cases using userdbctl
userdb support is optional, hence userdbctl may not be installed.
2026-06-05 04:56:34 +09:00
Frantisek Sumsal 70429d67d5 test: read the namespace symlink directly instead of using lsns
lsns scans all of /proc/*/ns/* even when a single PID is specified which
can be racy. Let's just read and compare the procfs symlinks directly to
both avoid doing the whole procfs scan and to, hopefully, get rid of the
occasional test fail where lsns fails to resolve the namespace for the
"old" process:

[ 1517.791471] TEST-07-PID1.sh[22279]: + systemd-run --unit=oldservice --property=Type=notify --property=NotifyAccess=all --property=PrivateUsers=true --property=PrivateNetwork=true bash -c 'systemd-notify --ready; exec sleep>
[ 1517.839514] TEST-07-PID1.sh[22329]: Running as unit: oldservice.service; invocation ID: 840ba49490f349c8b3b2116a43fb6f54
[ 1517.840403] TEST-07-PID1.sh[22335]: ++ systemctl show oldservice -p MainPID
[ 1517.841707] TEST-07-PID1.sh[22336]: ++ awk -F= '{print $2}'
[ 1517.849691] TEST-07-PID1.sh[22279]: + OLD_PID=22330
[ 1517.849691] TEST-07-PID1.sh[22279]: + systemd-run --unit=newservice --property=Type=notify --property=NotifyAccess=all --property=UserNamespacePath=/proc/22330/ns/user --property=NetworkNamespacePath=/proc/22330/ns/net bas>
[ 1517.951239] TEST-07-PID1.sh[22337]: Running as unit: newservice.service; invocation ID: 515b7f71240344aba2864e8510a18cbf
[ 1517.951475] TEST-07-PID1.sh[22343]: ++ awk -F= '{print $2}'
[ 1517.951915] TEST-07-PID1.sh[22342]: ++ systemctl show newservice -p MainPID
[ 1517.972557] TEST-07-PID1.sh[22279]: + NEW_PID=22338
[ 1517.972696] TEST-07-PID1.sh[22344]: ++ lsns -p 22330 -o NS -t net -n
[ 1518.003546] TEST-07-PID1.sh[22345]: ++ lsns -p 22338 -o NS -t net -n
[ 1518.030831] TEST-07-PID1.sh[22279]: + assert_eq '' 4026532280
[ 1518.031106] TEST-07-PID1.sh[22348]: + set +ex
[ 1518.031106] TEST-07-PID1.sh[22348]: FAIL: expected: '4026532280' actual: ''
[ 1518.031342] TEST-07-PID1.sh[111]: + echo 'Subtest /usr/lib/systemd/tests/testdata/units/TEST-07-PID1.user-namespace-path.sh failed'

Also, don't swallow the exit code from the command substitution in case
readlink fails, which could lead to a false-positive test result if it
happened for both readlinks.

Resolves: #39546
2026-06-05 04:39:00 +09:00
Luca Boccassi f723784b60 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.
2026-06-04 14:44:55 +01:00
Luca Boccassi b85a12dfb2 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.

Follow-up for 985a6fa44b
2026-06-03 14:02:44 +01:00
Zbigniew Jędrzejewski-Szmek 112b565756 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"]}]
```
2026-06-02 18:05:34 +02:00
Luca Boccassi 56a7febca7 sd-dlopen: deduplicate identical .note.dlopen notes
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>
2026-06-01 18:24:15 +01:00
Luca Boccassi d0443c6d1a 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.

Fixes https://github.com/systemd/systemd/issues/32712
2026-06-01 11:48:19 +02:00
Malformed C d35fa257eb nspawn: join network namespace before cloning user namespace
When both --private-users and --network-namespace-path are
specified, systemd-nspawn fails to start with "Operation not
permitted" during the setns() call.

This occurs because of the following execution sequence:
1. The outer child calls raw_clone() with CLONE_NEWUSER to create
   the new user namespace.
2. The inner child is spawned inside this new user namespace.
3. The inner child then attempts to call setns() to join the
   external network namespace.

Because the inner child is already running inside
the restricted user namespace, the kernel rejects
the setns() call to join a network namespace owned by
a different (host/more privileged) user namespace.

Fix this by moving the setns() call to the outer child, executing it
just before the raw_clone() call. This ensures the network namespace
is joined while the process still has the necessary privileges, which
also aligns with the inner child's expectation that the network
namespace is already set up upon entry.
2026-05-28 16:53:23 +09:00
Chris Patterson 779a3a13ae udev: preserve rule-set properties on failed network interface rename
When rename_netif() failed for a reason other than -EBUSY (e.g. -EEXIST
because NAME= conflicts with an existing interface), the revert path
rewrote the on-disk udev database from dev_db_clone (the pre-rules
snapshot) and then returned the error. The caller in
udev_event_execute_rules() bailed out before reaching the final
device_update_db(dev), so every property the rules had attached to the
device during this event (including ENV{}= assignments made alongside
the failing NAME=) was silently dropped from /run/udev/data/.

Persist 'dev' from inside the revert block, after its syspath and
INTERFACE have been restored. The cloned snapshot is still written
first to clear ID_RENAMING/ID_PROCESSING; the subsequent dev write
keeps the rule-applied properties without resurrecting the new name.
Only persist when r < 0, since the -EBUSY path returns success and the
caller will write the DB itself.

Add a TEST-17-UDEV.rename-netif regression test that pre-creates the
rename target, then triggers rules that set three ENV{}= properties
(one on a rule line before the failing NAME=, one on the same line as
NAME=, and one on a rule line after) and asserts all three are still
visible via udevadm info on the source interface. The neighbouring
test_netif_renaming_conflict already exercises the same -EEXIST revert
path but only checks the SYSTEMD_ALIAS broadcast, which is why this
regression went unnoticed.

Verified against unpatched origin/main (b4aff10ac0): the new test
fails, udevadm reports only kernel-supplied fields for the source
interface, and /run/udev/data/n<ifindex> is 0 bytes. With this patch
applied all three properties survive regardless of whether they were
set before, on, or after the failing NAME= rule line.

Downstream impact (NetworkManager managing an interface that rules had
marked NM_UNMANAGED=1): https://redhat.atlassian.net/browse/RHEL-178481

Fixes: https://github.com/systemd/systemd/issues/42331

Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 02:08:24 +09:00
Luca Boccassi 7b79004cce test: disable ManagedOOMMemoryPressure on /system.slice in TEST-55-OOMD
The systemd-oomd-defaults rpm installed on Fedora/CentOS images via
mkosi/mkosi.conf.d/centos-fedora/mkosi.conf ships
/usr/lib/systemd/system/system.slice.d/10-oomd-per-slice-defaults.conf:

    [Slice]
    ManagedOOMMemoryPressure=kill
    ManagedOOMMemoryPressureLimit=80%

https://gitlab.com/redhat/centos-stream/rpms/systemd/-/blob/c10s/10-oomd-per-slice-defaults.conf

In a recent flaky CI run on centos-10, the following sequence was
recorded in test/journal/TEST-55-OOMD-1.journal:

    [   77.740597] systemd-oomd[659]: Memory pressure for /system.slice is 85.03% > 80.00% for > 2s with reclaim activity
    [   77.745326] TEST-55-OOMD.sh[1292]: + journalctl --sync
    [   77.749125] systemd-oomd[659]: Considered 19 cgroups for killing, top candidates were:
    [   77.749128] systemd-oomd[659]:         Path: /system.slice/systemd-journald.service
    [   77.749134] systemd-oomd[659]:                 Current Memory Usage: 55.5M
    [   77.749597] systemd-oomd[659]: oomd attempting to kill 407 with KILL
    [   77.749670] systemd-oomd[659]: Marked /system.slice/systemd-journald.service for killing due to memory pressure for /system.slice being 85.03% > 80.00% for > 2s with reclaim activity
    [   77.752252] systemd[1]: systemd-journald.service: systemd-oomd killed 1 process(es) in this unit.
    [   77.752293] systemd[1]: systemd-journald.service: Changed running -> stop-sigterm
    [  329.922401] systemd[1]: systemd-journald.service: Main process exited, code=killed, status=9/KILL

PID 1292 (the test script) never logged anything after the
`journalctl --sync` line at [77.745326], and the unit stayed in
stop-sigterm until [329.922401].

Override /system.slice to ManagedOOMMemoryPressure=auto in the test
setup so the test does not rely on whichever per-slice oomd defaults
the distro happens to ship.

Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-26 21:49:10 +01:00
Luca Boccassi 39a2cc966b test: clean up persistent test state at beginning of TEST-64-UDEV-STORAGE too
This test often fails because the VM reboots (eg: kernel panic) and the
previous state is left unclean. Do the cleanups at the beginning too,
to try and reduce flakiness.
2026-05-26 15:09:01 +01:00
Luca Boccassi 4840da2fdf test: skip TEST-55-OOMD entirely if stress-ng is broken on this host
This reverts commit a17efef137 ("test: try to detect SIGILL in stress-ng
and skip TEST-55-OOMD gracefully") and replaces it with a single
check to skip the test cases.

The previous check was not reliable as stress-ng can catch SIGILL
itself and exist with an error:

  stress-ng[1068]: stress-ng: debug: [1068] caught SIGILL, address \
    0x00005632f8330140 (ILL_ILLOPN)
  stress-ng[1068]: stress-ng: debug: [1068] stress-ng: info: \
    0x00005632f8330140:<62>71 fd 48 6f 2d 36 14 1c 00 c5 d1 ef ed 49 29
  ...
  stress-ng[1053]: stress-ng: error: [1053] vm: [1061] terminated \
    with an error, exit status=2 (stressor failed)
  ...
  systemd[1]: TEST-55-OOMD-slowrule.service: Main process exited, \
    code=exited, status=2/INVALIDARGUMENT
  systemd[1]: TEST-55-OOMD-slowrule.service: Failed with result \
    'exit-code'.

Try to detect at the beginning of the test and skip the test case if it
happens.
2026-05-26 14:02:56 +02:00
Yu Watanabe c84bef3756 logind: migrate to Varlink (phase1) (#41561)
This implements phase 1 of #41560.

Add List Varlink methods for all logind object types (sessions, users,
seats, inhibitors).
2026-05-26 03:15:55 +09:00
Yu Watanabe ff5cd0b8da Add $SYSTEMD_INVOKED_AS (#42286) 2026-05-26 02:25:08 +09:00
Luca Boccassi 22a071a54d test: avoid picking volatile user-session units in varlinkctl-unit test
Each <type>_id is picked from a Unit.List '{}' call and immediately
queried via a second Unit.List '{"name":"<id>"}' call. When the picked
unit is tied to a user session (run-user-N.mount, user@N.service,
user-runtime-dir@N.service, session-cN.scope) it may be torn down
between the two calls if the user manager happens to exit at that
moment, causing a spurious NoSuchUnit failure.

Filter those out of the candidate lists for mount/service/scope.
Excerpt from a failed CI run showing the race:

  [ 2631.395826] systemd[1]: user-runtime-dir@4711.service: Trying to enqueue job user-runtime-dir@4711.service/stop/fail
  [ 2632.101414] systemd[1]: user-runtime-dir@4711.service: Got final SIGCHLD for state stop.
  [ 2632.182537] TEST-74-AUX-UTILS.sh[3051]: + mount_id=run-user-4711.mount
  [ 2632.186760] TEST-74-AUX-UTILS.sh[3099]: + varlinkctl call /run/systemd/io.systemd.Manager io.systemd.Unit.List '{"name":"run-user-4711.mount"}'
  [ 2632.189752] systemd[1]: varlink-api-3-3: Sending message: {"error":"io.systemd.Unit.NoSuchUnit"}
  [ 2632.190752] TEST-74-AUX-UTILS.sh[3099]: Method call io.systemd.Unit.List() failed: io.systemd.Unit.NoSuchUnit
  [ 2632.191594] TEST-74-AUX-UTILS.sh[101]: Subtest /usr/lib/systemd/tests/testdata/units/TEST-74-AUX-UTILS.varlinkctl-unit.sh failed

Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-25 17:33:16 +01:00
Luca Boccassi 868c2cd8e4 test: couple of fixes for TEST-87-AUX-UTILS-VM.vmspawn (#42291)
TEST-87-AUX-UTILS-VM.vmspawn is flaky, try to make it more robust

e.g.:
https://github.com/systemd/systemd/actions/runs/26373447540/job/77629553363
2026-05-25 14:39:06 +01:00
Luca Boccassi f6cd374e47 test: ignore both kill and wait errors in TEST-87-AUX-UTILS-VM.vmspawn
If the process already exited it's not just wait, but also kill that
will fail, so guard them both

Follow-up for d32bc9cd07
2026-05-25 12:58:04 +01:00
Luca Boccassi 89f13af5f9 test: bump varlinkctl timeout in TEST-87-AUX-UTILS-VM.vmspawn
10s is too short for flaky/overloaded CI, and it sometimes fails

Follow-up for d32bc9cd07
2026-05-25 12:58:04 +01:00
Luca Boccassi a17efef137 test: try to detect SIGILL in stress-ng and skip TEST-55-OOMD gracefully
The attempt to fix SIGILL in TEST-55-OOMD actually made the test more
flaky, as the chosen stress-ng method generates less pressure, so it
often fails.

Try a different approach: try to detect that SIGILL caused the unit
calling stress-ng to fail, and skip gracefully in that case.
2026-05-25 12:12:19 +01:00
Zbigniew Jędrzejewski-Szmek 94a1312cca TEST-75-RESOLVED: use SYSTEMD_INVOKED_AS=resolvconf 2026-05-25 12:37:36 +02:00
Luca Boccassi aac19fe468 Revert "test: pin stress-ng --vm-method to a portable scalar method in TEST-55-OOMD"
This reverts commit 881e4717c7.
2026-05-25 11:28:37 +01:00
Luca Boccassi 79ddf3c6f3 Revert "test: switch TEST-55-OOMD stress-ng --vm-method to lfsr32"
This reverts commit 4ac2369728.
2026-05-25 11:28:36 +01:00
Luca Boccassi 3fb520f010 pkcs11: switch to RSA-OAEP SHA-256/SHA-1
RSA PKCS#1 v1.5 is vulnerable to Bleichenbacher-style padding oracle
attacks, albeit very difficult and unlikely to actually happen in the
real world. Still for hardedning, switch new enrollments to RSA-OAEP,
with SHA-256 preferred and SHA-1 as fallback (probed at enrollment time,
since e.g. SoftHSM only accepts SHA-1, and older token might as well).

The actual padding scheme used to wrap a given key is recorded as a new
optional 'pkcs11-padding' / 'padding' field in the LUKS2 token JSON and
the homed user record. Decryption defaults to PKCS#1 v1.5 when absent so
existing enrollments keep working.
2026-05-22 14:09:16 +01:00
Luca Boccassi 86b389090d sysupdate: List default component only if transfer definition exists (#42179)
`sysupdate --json=short components` lists the components known to
sysupdate; these are the components which something like `updatectl`
will try to update.

The `default` component represents the host, and is meant to be listed
if transfer definitions exist in (for example) `/etc/sysupdate.d`
corresponding to the host OS. This then corresponds to `TARGET_HOST` in
`updatectl` and causes it to try updating that target.

The logic for working out whether the `default` component was present
essentially boiled down to “does `{/run,/etc,/usr/lib}/sysupdate.d`
exist”, and it didn’t check whether a `.transfer` or `.conf` file
actually existed in the config directory.

This is quite the corner case, but becomes more evident on systems where
sysupdate is being used to update a portable service but not the main
OS. At that point, if `/etc/sysupdate.d` exists empty (for some reason),
`updatectl` falls over because it starts trying to update the host OS
without any configuration to do so.

So, modify `sysupdate` to more fully load the available configuration
when listing components, and query it a bit more deeply to check whether
a default component exists.

If `sysupdate` is called with various command line arguments to affect
how its configuration is loaded, do *not* say that a default component
exists, as these arguments essentially anull the possibility of a
default being used in that process.

Add an integration test based on the reproducer provided by the issue
reporter. This test has been tested to fail if the changes to
`sysupdate.c` aren’t applied — if so, the second call to `sysupdate
components` would return
`{"default":true,"components":["some-component"]}`.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Fixes: https://github.com/systemd/systemd/issues/41501
2026-05-22 14:07:06 +01:00
Luca Boccassi 561f4cd866 bootctl: refactor get_file_version() (#42246) 2026-05-22 13:50:36 +01:00
Luca Boccassi 4bfc5ac457 report-basic: add a bunch more essential metrics (#42248) 2026-05-22 13:29:08 +01:00
Luca Boccassi d40f7a40c1 tpm2: measure user records on first login (#42228)
This is useful so that we can "blow a fuse" in TPM policies once a user
logged in.
2026-05-22 13:28:33 +01:00
Rocker Zhang 851ee29a54 test: cover LUO serialize-side anti-hijack guard in TEST-91
manager_luo_serialize_fd_stores() refuses to serialize a unit fd store
entry that holds a child LUO session named like PID 1's own ("systemd"),
to stop a service from hijacking PID 1's reserved session namespace
across kexec. That guard had no test coverage.

Add a test-luo store-hijack/check-hijack subcommand pair: on the first
boot a system service preserves a child LUO session named "systemd" in
its fd store; after kexec the test asserts the entry was not restored --
the unit's NFileDescriptorStore is 0, and check-hijack, run as the unit's
own second-boot ExecStart, confirms the hijack fd is absent from its
restored LISTEN_FDNAMES -- proving PID 1 skipped it during serialization.

The restore-side guards (corrupt mapping, reserved token 0, invalid unit
name, missing child session) are intentionally not covered: they only run
against PID 1's own "systemd" session built by luo_preserve_fd_stores(),
which a cooperating userspace helper cannot corrupt without racing or
displacing PID 1 (it single-owns /dev/liveupdate at shutdown). Triggering
them reliably would need kernel fault injection.

Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-22 12:00:05 +01:00
Philip Withnall 8de5a7b94d sysupdate: List default component only if transfer definition exists
`sysupdate --json=short components` lists the components known to
sysupdate; these are the components which something like `updatectl`
will try to update.

The `default` component represents the host, and is meant to be listed
if transfer definitions exist in (for example) `/etc/sysupdate.d`
corresponding to the host OS. This then corresponds to `TARGET_HOST` in
`updatectl` and causes it to try updating that target.

The logic for working out whether the `default` component was present
essentially boiled down to “does `{/run,/etc,/usr/lib}/sysupdate.d`
exist”, and it didn’t check whether a `.transfer` or `.conf` file
actually existed in the config directory.

This is quite the corner case, but becomes more evident on systems where
sysupdate is being used to update a portable service but not the main
OS. At that point, if `/etc/sysupdate.d` exists empty (for some reason),
`updatectl` falls over because it starts trying to update the host OS
without any configuration to do so.

So, modify `sysupdate` to more fully load the available configuration
when listing components, and query it a bit more deeply to check whether
a default component exists.

If `sysupdate` is called with various command line arguments to affect
how its configuration is loaded, do *not* say that a default component
exists, as these arguments essentially anull the possibility of a
default being used in that process.

Add an integration test based on the reproducer provided by the issue
reporter. This test has been tested to fail if the changes to
`sysupdate.c` aren’t applied — if so, the second call to `sysupdate
components` would return
`{"default":true,"components":["some-component"]}`.

Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Fixes: https://github.com/systemd/systemd/issues/41501
2026-05-22 11:46:32 +01:00
Lennart Poettering e3e897cf8f bootctl: refactor get_file_version() to use proper PE parsing
This irked me for a while. Let's not scan for strings stupidly, but
properly parse PE files to find the magic marker.

It's easy with our own PE APIs, hence we should do it.

This moves logging to the callers (previously, this was all mixed up).
2026-05-22 12:26:25 +02:00
Lennart Poettering ef9eddd202 report-basic: also report /etc/machine-info fields, just like os-release fields
The TAGS= field is really nice to have in reports, hence make this a
thing.
2026-05-22 12:17:09 +02:00
Lennart Poettering bbe2e14fe7 ci: add simple test case for new logic 2026-05-22 12:15:15 +02:00
Yaping Li d2bdaab55e logind: add ListInhibitors Varlink method
The Varlink ListInhibitors method is the counterpart of D-Bus
ListInhibitors. Like its D-Bus counterpart it is zero-filter and streams
the full list of currently registered inhibitors using the
SD_VARLINK_METHOD_MORE pattern, returning InhibitorInfo objects with
Id, What, Who, Why, Mode, UID, PID, and Since fields.

There is no D-Bus GetInhibitor getter to fold in, so no unique-key
filter is introduced here.
2026-05-22 02:56:24 +00:00
Yaping Li b4de3e5759 logind: add ListSeats Varlink method
The Varlink ListSeats method accepts an optional Id filter, folding in
the D-Bus GetSeat(s) lookup.

Passing Id yields a single reply on match, or NoSuchSeat on miss.
Passing no Id with the 'more' flag streams the full list; passing no
Id without 'more' resolves to the caller's seat (preserving the
ergonomic default of GetSeat). The Id filter supports the special
names "self" and "auto" which resolve to the caller's seat.

The SeatInfo type in the io.systemd.Login Varlink IDL carries all seat
properties matching the D-Bus org.freedesktop.login1.Seat interface.
2026-05-22 02:56:24 +00:00
Yaping Li 355f73a564 logind: add ListUsers Varlink method
The Varlink ListUsers method accepts optional UID and PID filters,
folding in the D-Bus GetUser(u) and GetUserByPID(u) lookups.

Passing a unique-key filter (UID and/or PID) yields a single reply on
match, or NoSuchUser on miss. Passing no filter with the 'more' flag
streams the full list; passing no filter without 'more' resolves to
the caller's user (preserving the ergonomic default of GetUser). If
both UID and PID are specified they must reference the same user,
otherwise NoSuchUser is returned.

The UserInfo type in the io.systemd.Login Varlink IDL carries all
user properties matching the D-Bus org.freedesktop.login1.User
interface.
2026-05-22 02:56:24 +00:00
Yaping Li 1f9fb6300b logind: add ListSessions Varlink method
The Varlink ListSessions method accepts optional Id and PID filters,
folding in the D-Bus GetSession(s) and GetSessionByPID(u) lookups.

Passing a unique-key filter (Id and/or PID) yields a single reply on
match, or NoSuchSession on miss. Passing no filter streams the full
list (requires the 'more' flag). Specifying both Id and PID acts as a
consistency check: both must refer to the same session, otherwise
NoSuchSession is returned.

The Id filter supports the special names "self" and "auto" which
resolve to the caller's session. The SessionInfo type in the
io.systemd.Login Varlink IDL carries all session properties matching
the D-Bus org.freedesktop.login1.Session interface.
2026-05-22 02:56:24 +00:00
Lennart Poettering 9a28e54b54 ci: add test for new machine-tags concept 2026-05-21 18:30:16 +02:00
Lennart Poettering 7f5503f15d tpm2: add nvpcr allocation priorities (#42227)
nvindex space is very scarce, let's hence introduce "priorities" on
nvpcrs, so that if we haven't got enough space for all we have some
control which ones get dropped and which ones kept.
2026-05-21 18:19:39 +02:00
Daan De Meyer ecaac1c0a2 TEST-08-INITRD: Set up exitrd on boot rather than including in image
Just copy the initramfs from the VM rather than doing it during
the image build.
2026-05-21 18:06:07 +02:00
Rocker Zhang 1bd2acf193 test: cover lingering users surviving a soft-reboot in TEST-82
Regression coverage for the soft-reboot linger bug fixed in
9f25feb4ed ("logind: keep lingering users at startup-time GC", #41789):
a lingering user's user@.service was started after a hardware reboot but
not after `systemctl soft-reboot`, because logind GC'd the user at
startup before user_start() ran.

On the first boot, enable lingering for the pre-existing testuser and
wait for its user@UID.service to come up. After the first soft-reboot
(which keeps the same persistent rootfs), assert the service is active
again — this is the regression check. Disable lingering again before the
nextroot switch in the second boot so the lingering user doesn't leak
into the later boots' minimal overlay rootfs.

Verified locally in a qemu/KVM VM: passes with the fix present, and with
the fix reverted the second-boot assertion times out (the lingering user
is GC'd in logind startup and user@UID.service never comes back),
confirming the test exercises the bug.

Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-21 16:02:43 +01:00