Commit Graph
60395 Commits
Author SHA1 Message Date
Daan De Meyer 6ec161c5b9 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.
2026-05-29 16:13:29 +02:00
Daan De Meyer 0a63318420 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. */
2026-05-29 16:12:45 +02:00
Luca Boccassi 67411a3f09 oom: use cgroup.kill if available
The log message is informational only, same as the count of killed
processes, so we can safely use cgroup.kill when available instead
of manually recursing through the cgroup tree.
2026-05-29 12:02:29 +01:00
Luca Boccassi 92a5bf2c02 cgroup: optionally check number of tasks before cgroup.kill
This of course cannot be atomic, but for informational purposes it
should be good enough
2026-05-28 20:55:01 +01:00
Luca Boccassi 39bec38eb1 cgtop: use cg helper to parse pids.current 2026-05-28 20:55:01 +01:00
Yu Watanabe f8fbee74ba network: mention interface name in polkit details
Closes #42274.
2026-05-29 04:34:18 +09:00
jeffhuang 0c5cba6420 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>
2026-05-29 04:30:48 +09:00
Zbigniew Jędrzejewski-Szmek 97a0ec135b Downgrade warning about missing libseccomp
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.

C.f. https://bugzilla.redhat.com/show_bug.cgi?id=2463540.
2026-05-29 01:09:19 +09:00
Lennart Poettering eb3799a373 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.
2026-05-28 13:33:08 +01:00
Zbigniew Jędrzejewski-Szmek bf4388ab31 repart: constify Context* params 2026-05-28 12:06:12 +02:00
Zbigniew Jędrzejewski-Szmek fa2a6b6d88 shared/mkfs-util: split out mkfs_find_or_warn() 2026-05-28 12:06:10 +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
Yu Watanabe 68af89e619 meson: move simple test entries 2026-05-28 16:44:29 +09:00
Daan De Meyer d4aa9dcda5 test: stop using PATH_TEST()/QMP_TEST() macro to make not confuse gcc/gcov/lcov (#42338) 2026-05-28 09:33:22 +02:00
jeffhuang 73fea38cf1 hwdb: bounds-check trie offsets against the mmap before dereferencing
Fixes a family of OOB reads in the trie walker where attacker-controlled
offsets are loaded from a (possibly hostile) hwdb.bin and added to
hwdb->map without first checking that the resulting pointer stays inside
the mapping. Crash sites:

  - trie_fnmatch_f               sd-hwdb.c:187   (#42340)
  - trie_search_f                sd-hwdb.c:233   (#42341)
  - trie_children_cmp_f /bsearch sd-hwdb.c:94    (#42342)
  - hwdb_add_property            sd-hwdb.c:121   (#42343)
  - trie_node_from_off (UBSAN)   sd-hwdb.c:83
  - trie_fnmatch_f stack overflow on cyclic children (CIFuzz finding)

Commit b45a897edc ("hwdb: reject out-of-bounds fnmatch prefixes")
plugged the first site only at the prefix_off-content level, but the
crash on the read of node->prefix_off itself still happens when node is
already OOB. This is the structural fix: a single hwdb_at() helper
validates that [off, off + size) lies inside the mapping, and
trie_node_from_off() / trie_string() return NULL on OOB; every caller
treats the result as nullable and surfaces -EBADMSG.

trie_fnmatch_f() additionally caps its recursion depth at 2048; without
the cap a corrupt trie whose child offsets form a cycle (or just a deep
linear chain) drives the parser into stack-overflow rather than
returning -EBADMSG (caught by CIFuzz address sanitizer on this branch).

Additions:

  - A fuzz-hwdb libFuzzer harness that drives sd_hwdb_new_from_path,
    sd_hwdb_get, sd_hwdb_seek, and sd_hwdb_enumerate on attacker bytes.
  - Five hand-crafted unit tests in test-sd-hwdb.c (one per crash
    bucket, plus the cyclic-trie recursion case) that build a malformed
    in-memory hwdb.bin and assert -EBADMSG rather than SIGSEGV /
    stack-overflow.
  - Regression corpus files under test/fuzz/fuzz-hwdb/ pinning each
    fixed bucket, including the CIFuzz stack-overflow reproducer.

Closes #42340.
Closes #42341.
Closes #42342.
Closes #42343.

Reported-by: AI-assisted libFuzzer campaign
Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 15:05:24 +09:00
Luca Boccassi 6f31db9b07 test-oomd: drop racy last_had_mem_reclaim assertion
test_oomd_cgroup_context_acquire_and_insert sets c1->pgscan = UINT64_MAX
and c1->last_had_mem_reclaim = 888 before re-inserting via
oomd_insert_cgroup_context(h1, h2, cgroup), then asserts that c2 carries
over last_had_mem_reclaim == 888.

The assumption was that, because c1->pgscan (which becomes c2->last_pgscan)
is UINT64_MAX and is therefore strictly greater than the freshly-acquired
c2->pgscan, oomd_pgscan_rate() in oomd_insert_cgroup_context() would
return 0 and leave last_had_mem_reclaim untouched. But the function
treats last_pgscan > pgscan as "cgroup was recreated", resets last_pgscan
to 0, and returns pgscan - 0 == pgscan. So when the kernel records any
non-zero pgscan on the live cgroup of the test unit, the rate is > 0 and
last_had_mem_reclaim is overwritten with now(CLOCK_MONOTONIC).

From src/oom/oomd-util.c:

    uint64_t oomd_pgscan_rate(const OomdCGroupContext *c) {
            [...]
            last_pgscan = c->last_pgscan;
            if (c->last_pgscan > c->pgscan) {
                    log_debug("Last pgscan %"PRIu64" greater than current pgscan %"PRIu64" for %s. Using last pgscan of zero.",
                                    c->last_pgscan, c->pgscan, c->path);
                    last_pgscan = 0;
            }
            return c->pgscan - last_pgscan;
    }

    int oomd_insert_cgroup_context(Hashmap *old_h, Hashmap *new_h, const char *path) {
            [...]
            if (oomd_pgscan_rate(curr_ctx) > 0)
                    curr_ctx->last_had_mem_reclaim = now(CLOCK_MONOTONIC);

Under sanitizers the test can be slow enough that the kernel scans the
test service cgroup at least once between the two acquisitions, which
triggers the failure:

    [ 1898.159455] test-oomd-util[2606]: /* test_oomd_cgroup_context_acquire_and_insert */
    [ 1898.161247] test-oomd-util[2606]: Last pgscan 18446744073709551615 greater than current pgscan 2 for /system.slice/test-oomd-util.service. Using last pgscan of zero.
    [ 1898.161330] test-oomd-util[2606]: src/oom/test-oomd-util.c:322: Assertion failed: Expected "c2->last_had_mem_reclaim == 888u", but 1898161250 != 888

(1898161250 matches the monotonic timestamp of the log line, confirming
that last_had_mem_reclaim was overwritten with now(CLOCK_MONOTONIC).)

The propagation of last_had_mem_reclaim is already covered
deterministically by TEST(oomd_update_cgroup_contexts_between_hashmaps),
which builds OomdCGroupContext structs directly with matching pgscan
values so that oomd_pgscan_rate() returns exactly 0. So just drop the
racy setup and assertion here.

Follow-up for df637ede7b

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

Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-28 15:01:43 +09:00
Luca Boccassi 004401fd06 resolve: validate short RSA DNSKEY blobs
Reject malformed RSA DNSKEY data before reading the extended exponent
header, and add a regression test.

Co-developed-by: GitHub Copilot (GPT 5.5) <copilot@github.com>
2026-05-28 15:00:51 +09:00
Yu Watanabe 071493c725 test-pressure: set timeout to make not wait forever
If this runs on a slow or busy machine, then we may not get enough
pressure to trigger the event sources. In such case, the test does not
finish. It is problematic when the test is _not_ run with 'meson test',
e.g. debian/ubuntu CIs.

Let's introduce a timeout for each event loop, and skip test cases
gracefully.
2026-05-27 21:34:04 +01: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
Yu Watanabe 521153fe5b test-qmp-client: drop QMP_TEST() macro
Similar to the previous commit for test-path.
The macro confuses gcc/gcov/lcov:
```
lcov: ERROR: lcov: ERROR: (inconsistent) mismatched end line for test_qmp_client_basic_body at
/home/runner/work/systemd/systemd/src/test/test-qmp-client.c:204:
204 -> 224 while capturing from build/mkosi.builddir/arch~rolling~x86-64/test-qmp-client.p/src_test_test-qmp-client.c.gcno
```

The macro itself is not bad, but does not reduce lines so much.
Let's stop using the macro.
2026-05-28 01:46:38 +09:00
Frantisek Sumsal 223ca6d2d3 import: don't assert on missing signature file
Since ac9edf9911 even the per-file
verification style uses detached signatures instead of inline ones.
That commit dropped the inline verification fallback, but it didn't
update the raw_pull_job_on_finished()/tar_pull_job_on_finished()
callbacks, which caused the per-file verification to silently fall
through the signature check and eventually hit the now unconditional
assert in pull_verify():

~# importctl pull-tar -mN https://distfiles.gentoo.org/releases/amd64/autobuilds/20260426T153103Z/stage3-amd64-systemd-20260426T153103Z.tar.xz
...
Acquired 1.2G for https://distfiles.gentoo.org/releases/amd64/autobuilds/20260426T153103Z/stage3-amd64-systemd-20260426T153103Z.tar.xz.
Download of https://distfiles.gentoo.org/releases/amd64/autobuilds/20260426T153103Z/stage3-amd64-systemd-20260426T153103Z.tar.xz complete.
SHA256 checksum of https://distfiles.gentoo.org/releases/amd64/autobuilds/20260426T153103Z/stage3-amd64-systemd-20260426T153103Z.tar.xz is valid.
Assertion 'signature_job->state == PULL_JOB_DONE' failed at src/import/pull-common.c:588, function pull_verify(). Aborting.

To fix this, let's drop the now outdated guards from the callbacks,
given that both per-file and per-directory verification uses detached
signatures. Also, drop some dead code along the way, given we no longer
need to even determine the verification style anymore.

With this, the reproducer above now shows a proper error:

...
Acquired 1.2G for https://distfiles.gentoo.org/releases/amd64/autobuilds/20260426T153103Z/stage3-amd64-systemd-20260426T153103Z.tar.xz.
Download of https://distfiles.gentoo.org/releases/amd64/autobuilds/20260426T153103Z/stage3-amd64-systemd-20260426T153103Z.tar.xz complete.
Failed to retrieve signature file, cannot verify. (Try --verify=no?)

Also, both --verify=checksum/--verify=no keep working as expected.

Follow-up for ac9edf9911.
Resolves: #41895
2026-05-28 01:24:54 +09:00
Yu Watanabe f5678af9c7 test-path: coding style cleanups 2026-05-28 01:23:48 +09:00
Yu Watanabe bd6b38d74e test-path: drop PATH_TEST() macro
The macro was introduced by fc7a32df38,
but unfortunately gcc/gcov/lcov are confused by the macro:
```
lcov: ERROR: lcov: ERROR: (inconsistent) mismatched end line for test_path_exists_body at
/home/runner/work/systemd/systemd/src/test/test-path.c:158:
158 -> 185 while capturing from build/mkosi.builddir/arch~rolling~x86-64/test-path.p/src_test_test-path.c.gcno
(use "lcov --ignore-errors inconsistent ..." to bypass this error)
```

The macro deos nothing spurious, hence it should be a bug in gcc.
But, the macro just reduces the lines for calling setup_test(), and
does not simplify test cases so much.
Let's call it in each test cases, and stop using the macro.
2026-05-28 01:23:48 +09:00
Zbigniew Jędrzejewski-Szmek cd79e5620b dhcp: update test and header cleanup (#42256) 2026-05-27 14:23:34 +02:00
Zbigniew Jędrzejewski-Szmek b130084a2d shared/bus-polkit: fix punctuation 2026-05-27 14:05:08 +02:00
nikstur b4aff10ac0 meson: fix building without logind (#42324)
Otherwise you cannot build systemd (e.g. just the libs) without logind.

Follow-up for 1f9fb6300b
2026-05-26 23:45:18 +01:00
Zbigniew Jędrzejewski-Szmek 7d6a3d9f3c imds: suppress or downgrade log messages
Other places that read credentials filer out ENXIO:
$ journalctl -b -u systemd-imds-early-network.service -o short-monotonic --no-hostname --no-pager -p warning
[    5.477675] systemd-imdsd[473]: Failed to read credential 'imds.vendor', ignoring: No such device or address
[    5.477687] systemd-imdsd[473]: Failed to read credential 'imds.vendor_token', ignoring: No such device or address
[    5.477693] systemd-imdsd[473]: Failed to read credential 'imds.refresh_header_name', ignoring: No such device or address
[    5.477699] systemd-imdsd[473]: Failed to read credential 'imds.data_url', ignoring: No such device or address
[    5.477704] systemd-imdsd[473]: Failed to read credential 'imds.data_url_suffix', ignoring: No such device or address
[    5.477710] systemd-imdsd[473]: Failed to read credential 'imds.token_header_name', ignoring: No such device or address
[    5.477714] systemd-imdsd[473]: Failed to read credential 'imds.extra_header', ignoring: No such device or address
[    5.477720] systemd-imdsd[473]: Failed to read credential 'imds.extra_header2', ignoring: No such device or address
[    5.477730] systemd-imdsd[473]: Failed to read credential 'imds.extra_header3', ignoring: No such device or address
[    5.477736] systemd-imdsd[473]: Failed to read credential 'imds.extra_header4', ignoring: No such device or address
[    5.477742] systemd-imdsd[473]: Failed to read credential 'imds.extra_header5', ignoring: No such device or address
[    5.477747] systemd-imdsd[473]: Failed to read credential 'imds.extra_header6', ignoring: No such device or address
[    5.477751] systemd-imdsd[473]: Failed to read credential 'imds.extra_header7', ignoring: No such device or address
[    5.477757] systemd-imdsd[473]: Failed to read credential 'imds.extra_header8', ignoring: No such device or address
[    5.477763] systemd-imdsd[473]: Failed to read credential 'imds.extra_header9', ignoring: No such device or address
[    5.477768] systemd-imdsd[473]: Failed to read credential 'imds.extra_header10', ignoring: No such device or address
[    5.477774] systemd-imdsd[473]: Failed to read credential 'imds.extra_header11', ignoring: No such device or address
[    5.477779] systemd-imdsd[473]: Failed to read credential 'imds.extra_header12', ignoring: No such device or address
[    5.477784] systemd-imdsd[473]: Failed to read credential 'imds.extra_header13', ignoring: No such device or address
[    5.477789] systemd-imdsd[473]: Failed to read credential 'imds.extra_header14', ignoring: No such device or address
[    5.477799] systemd-imdsd[473]: Failed to read credential 'imds.extra_header15', ignoring: No such device or address
[    5.477804] systemd-imdsd[473]: Failed to read credential 'imds.extra_header16', ignoring: No such device or address
[    5.477810] systemd-imdsd[473]: Failed to read credential 'imds.extra_header17', ignoring: No such device or address
[    5.477815] systemd-imdsd[473]: Failed to read credential 'imds.extra_header18', ignoring: No such device or address
[    5.477820] systemd-imdsd[473]: Failed to read credential 'imds.extra_header19', ignoring: No such device or address
[    5.477825] systemd-imdsd[473]: Failed to read credential 'imds.extra_header20', ignoring: No such device or address
[    5.477830] systemd-imdsd[473]: Failed to read credential 'imds.extra_header21', ignoring: No such device or address
[    5.477835] systemd-imdsd[473]: Failed to read credential 'imds.extra_header22', ignoring: No such device or address
[    5.477840] systemd-imdsd[473]: Failed to read credential 'imds.extra_header23', ignoring: No such device or address
[    5.477845] systemd-imdsd[473]: Failed to read credential 'imds.extra_header24', ignoring: No such device or address
[    5.477851] systemd-imdsd[473]: Failed to read credential 'imds.extra_header25', ignoring: No such device or address
[    5.477856] systemd-imdsd[473]: Failed to read credential 'imds.extra_header26', ignoring: No such device or address
[    5.477865] systemd-imdsd[473]: Failed to read credential 'imds.extra_header27', ignoring: No such device or address
[    5.477869] systemd-imdsd[473]: Failed to read credential 'imds.extra_header28', ignoring: No such device or address
[    5.477874] systemd-imdsd[473]: Failed to read credential 'imds.extra_header29', ignoring: No such device or address
[    5.477881] systemd-imdsd[473]: Failed to read credential 'imds.extra_header30', ignoring: No such device or address
[    5.477885] systemd-imdsd[473]: Failed to read credential 'imds.extra_header31', ignoring: No such device or address
[    5.477890] systemd-imdsd[473]: Failed to read credential 'imds.extra_header32', ignoring: No such device or address
[    5.477896] systemd-imdsd[473]: Failed to read credential 'imds.extra_header33', ignoring: No such device or address
[    5.477901] systemd-imdsd[473]: Failed to read credential 'imds.extra_header34', ignoring: No such device or address
[    5.477906] systemd-imdsd[473]: Failed to read credential 'imds.extra_header35', ignoring: No such device or address
[    5.477913] systemd-imdsd[473]: Failed to read credential 'imds.extra_header36', ignoring: No such device or address
[    5.477917] systemd-imdsd[473]: Failed to read credential 'imds.extra_header37', ignoring: No such device or address
[    5.477922] systemd-imdsd[473]: Failed to read credential 'imds.extra_header38', ignoring: No such device or address
[    5.477931] systemd-imdsd[473]: Failed to read credential 'imds.extra_header39', ignoring: No such device or address
[    5.477935] systemd-imdsd[473]: Failed to read credential 'imds.extra_header40', ignoring: No such device or address
[    5.477940] systemd-imdsd[473]: Failed to read credential 'imds.extra_header41', ignoring: No such device or address
[    5.477945] systemd-imdsd[473]: Failed to read credential 'imds.extra_header42', ignoring: No such device or address
[    5.477951] systemd-imdsd[473]: Failed to read credential 'imds.extra_header43', ignoring: No such device or address
[    5.477956] systemd-imdsd[473]: Failed to read credential 'imds.extra_header44', ignoring: No such device or address
[    5.477962] systemd-imdsd[473]: Failed to read credential 'imds.extra_header45', ignoring: No such device or address
[    5.477967] systemd-imdsd[473]: Failed to read credential 'imds.extra_header46', ignoring: No such device or address
[    5.477972] systemd-imdsd[473]: Failed to read credential 'imds.extra_header47', ignoring: No such device or address
[    5.477978] systemd-imdsd[473]: Failed to read credential 'imds.extra_header48', ignoring: No such device or address
[    5.477982] systemd-imdsd[473]: Failed to read credential 'imds.extra_header49', ignoring: No such device or address
[    5.477988] systemd-imdsd[473]: Failed to read credential 'imds.extra_header50', ignoring: No such device or address
[    5.477995] systemd-imdsd[473]: Failed to read credential 'imds.extra_header51', ignoring: No such device or address
[    5.477999] systemd-imdsd[473]: Failed to read credential 'imds.extra_header52', ignoring: No such device or address
[    5.478022] systemd-imdsd[473]: Failed to read credential 'imds.extra_header53', ignoring: No such device or address
[    5.478028] systemd-imdsd[473]: Failed to read credential 'imds.extra_header54', ignoring: No such device or address
[    5.478033] systemd-imdsd[473]: Failed to read credential 'imds.extra_header55', ignoring: No such device or address
[    5.478039] systemd-imdsd[473]: Failed to read credential 'imds.extra_header56', ignoring: No such device or address
[    5.478044] systemd-imdsd[473]: Failed to read credential 'imds.extra_header57', ignoring: No such device or address
[    5.478050] systemd-imdsd[473]: Failed to read credential 'imds.extra_header58', ignoring: No such device or address
[    5.478055] systemd-imdsd[473]: Failed to read credential 'imds.extra_header59', ignoring: No such device or address
[    5.478060] systemd-imdsd[473]: Failed to read credential 'imds.extra_header60', ignoring: No such device or address
[    5.478066] systemd-imdsd[473]: Failed to read credential 'imds.extra_header61', ignoring: No such device or address
[    5.478071] systemd-imdsd[473]: Failed to read credential 'imds.extra_header62', ignoring: No such device or address
[    5.478079] systemd-imdsd[473]: Failed to read credential 'imds.extra_header63', ignoring: No such device or address
[    5.478086] systemd-imdsd[473]: Failed read IPv4 address from credential 'imds.address_ipv4', ignoring: No such device or address
[    5.478091] systemd-imdsd[473]: Failed read IPv6 address from credential 'imds.address_ipv6', ignoring: No such device or address
[    5.478097] systemd-imdsd[473]: Failed to read credential 'imds.key_hostname', ignoring: No such device or address
[    5.478102] systemd-imdsd[473]: Failed to read credential 'imds.key_region', ignoring: No such device or address
[    5.478107] systemd-imdsd[473]: Failed to read credential 'imds.key_zone', ignoring: No such device or address
[    5.478113] systemd-imdsd[473]: Failed to read credential 'imds.key_ipv4_public', ignoring: No such device or address
[    5.478119] systemd-imdsd[473]: Failed to read credential 'imds.key_ipv6_public', ignoring: No such device or address
[    5.478123] systemd-imdsd[473]: Failed to read credential 'imds.key_ssh_key', ignoring: No such device or address
[    5.478128] systemd-imdsd[473]: Failed to read credential 'imds.key_userdata', ignoring: No such device or address
[    5.478134] systemd-imdsd[473]: Failed to read credential 'imds.key_userdata_base', ignoring: No such device or address
[    5.478137] systemd-imdsd[473]: Failed to read credential 'imds.key_userdata_base64', ignoring: No such device or address
2026-05-27 04:36:05 +09:00
Zbigniew Jędrzejewski-Szmek 0dc188e006 units: do not fail if imds is not configured
In https://bugzilla.redhat.com/show_bug.cgi?id=2481466, it is reported
that systemd-imds-early-network.service fails on AWS EC2 instance with:

> No IMDS endpoint information provided or detected, cannot operate.

The service will be started on various systems where it doesn't have
enough configuration to run. The systemd-imds-generator only does some
superficial checks, so the tool should not mark the boot as failed
it turns out that IMDS is not supported.
2026-05-27 04:36:05 +09:00
Yu Watanabe e329ef572d udev: ignore errors in adding property with spurious value
Since a62cd5a153, when an invalid property
is being added, device_add_property() refuses it with -EINVAL.
Before the commit, the function could fail with only -ENOMEM, and if it fails,
processing udev rules was aborted.

Let's not hard fail when udev rules or udev builtins try to add an invalid
property, and let's just log and ignore the failure.

Follow-up for a62cd5a153.

Fixes #41339 and #41296.
2026-05-27 04:04:47 +09:00
Yu Watanabe 0f80db1359 network: add skelton for new DHCP relay settings
Follow-up for 1a75eb7d8b.
2026-05-26 18:51:26 +01:00
Frantisek Sumsal 2e117e270d nspawn: mark --bind-user-shell=/BindUserShell= as trusted
Similarly to --bind-user=/BindUser=.

Follow-up for a9e860f22e.

Reported-by: omkhar <omkhar@users.noreply.github.com>
2026-05-26 17:44:02 +02:00
Zbigniew Jędrzejewski-Szmek c621879e35 imds-generator: replace static Condition=initrd by a check in the generator
After looking at the unit, I'm not sure if systemd-imds-import.service
is supposed to run in the host system or not. But if it is supposed to
only run in the initrd, then the static condition in the unit file gives
as the worst behaviour: the generator does not do any checks if we are
in the initrd or not, and if it enabled the unit, it'll influence the
transaction ordering (possibly causing loops or additional work) and
then the unit will be unconditionally skipped. So replace the static
condition by a check in the generator. If the user specifies
systemd.imds.import on the commandline, it'll be honoured also in the
host.
2026-05-26 13:58:53 +01:00
Yu Watanabe 754737ddc3 test-execute: reenable the test with sanitizers 2026-05-26 14:30:22 +02:00
Mikhail Nogin d096763827 dissect-image: reject empty partitions array
di is allocated while iterating over p.partitions. If the array is
empty,
the loop is skipped and di remains NULL, but the code still assigns
image
metadata through it.

Return EBADMSG before accessing di in this case.

Found by Linux Verification Center (linuxtesting.org) with Svace.
2026-05-26 17:53:27 +09:00
Yu Watanabe 6f5100bf12 login: split-out common varlink filed definitions
Only effective change is that now Remote field is nullable on
ListSession, even though logind always provides the field.
But that should not be a big matter.

C.f. https://github.com/systemd/systemd/pull/41561#discussion_r3218411455
2026-05-26 17:52:07 +09:00
Daan De Meyer e098b57810 test-pressure: Fix checks
Follow up for 7e250f70
2026-05-26 00:03:20 +01:00
Yu Watanabe ba8f9b6cc1 Revert "test: skip tpm2 test on s390x on GHA"
This reverts commit b735d01c8a.

Closes #38229.
2026-05-25 22:17:00 +01:00
Yu Watanabe 21c91145ff test-execute: drop workaround for fixed issue
The issue should be already fixed by f01f70a9a3.
2026-05-25 22:16:16 +01: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
Mikhail Nogin f50c3f548b sysusers: log new group name on write failure
When adding new groups, putgrent_with_members() is called with the newly
constructed group n, but the error path logs gr->gr_name. gr belongs to
the
earlier loop over the existing group file and may be NULL after EOF.

Log n.gr_name instead.

Found by Linux Verification Center (linuxtesting.org) with Svace.
2026-05-26 02:21:50 +09:00
Zbigniew Jędrzejewski-Szmek 58e7959988 Add $SYSTEMD_INVOKED_AS
This allows multi-call binaries to be easily invoked with a different
name. After installation, the name is set by creating a symlink. But in
build directories, we don't create the symlinks. (There are also other
ways to achieve the same thing, e.g. zsh supports $ARGV0, and exec -a
can be used, but those are either non-portable or are more complicated
to use.)  The primary use-case for me is to test --help output for
multicall binaries.

Also reorder the help for env vars to group the more generic ones near
the top.

This was initially proposed in https://github.com/systemd/systemd/pull/24054,
but there were some comments about the implementation. I had a branch
with the patch, but I don't think I ever actually submitted it as a
pull request.
2026-05-25 12:37:36 +02:00
Lennart Poettering e851b0fe9d Some fixes found by AI (#42263) 2026-05-25 07:06:24 +02:00
Daan De Meyer d60cf3702a test-pressure: Skip if controller didn't get enabled
If for any reason the controller didn't get enabled on the
scope, skip the test.
2026-05-24 22:36:27 +01:00
Luca Boccassi ef8c5548ca nspawn: downgrade log level when unregistering and machine is already gone
nspawn started logging at notice level when exiting a container:

root@sid-arm64:~# exit
logout
Container sid-arm64 exited successfully.
Failed to unregister machine in system context, ignoring: No such device or address

Looks like it's racing with machined which already noticed it was
gone and remove it. Downgrade to debug on ENXIO.

Follow-up for 1e084aad7d
2026-05-24 21:18:58 +02:00
Luca Boccassi a7ecad77cb shared/options: fix crash by aligning struct to sizeof(void*)
On some architectures like m68k, alignof(void*) is 2, not sizeof(void*)
(which is 4). So the natural alignment of struct Option is 2 and
sizeof(Option) == 26.

However, each variable placed in the SYSTEMD_OPTIONS ELF section via
_OPTION() carries _alignptr_ (= __attribute__((aligned(sizeof(void*))))),
which forces each entry to start at a 4-byte boundary. The linker
therefore inserts 2 bytes of padding between adjacent entries, producing
an actual stride of 28 in the section.

option_parse() iterates over the section with pointer arithmetic
("opt++"), which advances by sizeof(Option) == 26 and lands inside the
padding. The fields read back as zero, and since commit cf88903637
("tree-wide: get rid of most uses of ALIGN_PTR") added the ordering
assertion below, the resulting "0 < 0" trips it when running --help:

 Assertion 'opt->id < (opt + 1)->id' failed at src/shared/options.c:116, function option_parse(). Aborting.

 #0  0xc0a7b248 in ?? () from /usr/lib/m68k-linux-gnu/libc.so.6
 #1  0xc0a7b2ce in pthread_kill () from /usr/lib/m68k-linux-gnu/libc.so.6
 #2  0xc0a2edc6 in raise () from /usr/lib/m68k-linux-gnu/libc.so.6
 #3  0xc0a1c128 in abort () from /usr/lib/m68k-linux-gnu/libc.so.6
 #4  0xc05c6f78 in option_parse (options=0x0, options_end=0x0, state=0xc09ca968) at ../src/shared/options.c:116

Fix this by applying _alignptr_ to the struct definition itself, so that
sizeof(Option) is padded up to a multiple of sizeof(void*) and matches
the actual on-disk stride. Add an assert_cc() so any future regression
is caught at compile time.

The same latent bug applies to Verb and TestFunc, which use the same
section-placement pattern. Their natural sizeof was already a multiple
of sizeof(void*) so no crash was observed, but apply the same fix
defensively.

Follow-up for cf88903637

Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 20:36:56 +02:00
Daan De Meyer 112453b9a2 io-util: Drop faulty assumption that poll flags == epoll flags
Not the case on the sparc architecture. Replace with two translation
functions. The poll to epoll variant isn't used yet but will be used
when we add io-uring support to sd-event so we already add it here so
that it is in place.

Follow-up for cf4c65afa8
2026-05-24 20:36:43 +02:00
Luca Boccassi a05fe6684a libc: dlsym the time64 alias for epoll_pwait2() on 32-bit _TIME_BITS=64
Commit f795d54591 ("libc,shared: detect newer library symbols at
runtime") replaced the build-time HAVE_EPOLL_PWAIT2 gate with a runtime
shim that resolves the libc symbol via dlsym(RTLD_DEFAULT, "epoll_pwait2").
That breaks on 32-bit architectures built with _TIME_BITS=64 (e.g. Debian
armhf since the time64 transition).

When _TIME_BITS=64 is in effect on a 32-bit target, glibc's <sys/epoll.h>
asm-renames the C identifier `epoll_pwait2` to the matching 64-bit-time_t
ABI symbol `__epoll_pwait2_time64`, so a normal C call resolves to the
variant whose `struct timespec` layout (16 bytes: s64 tv_sec, long tv_nsec,
long pad) matches what the compiler is using:

    /* /usr/include/sys/epoll.h */
    #ifndef __USE_TIME64_REDIRECTS
    extern int epoll_pwait2 (int __epfd, struct epoll_event *__events,
                             int __maxevents,
                             const struct timespec *__timeout,
                             const __sigset_t *__ss) ...;
    #else
    # ifdef __REDIRECT
    extern int __REDIRECT (epoll_pwait2, (int __epfd, ...,
                                          const struct timespec *__timeout,
                                          const __sigset_t *__ss),
                           __epoll_pwait2_time64) ...;
    # else
    #  define epoll_pwait2 __epoll_pwait2_time64
    # endif
    #endif

dlsym() doesn't see that header-level rename and returns the legacy
32-bit-time_t `epoll_pwait2` symbol, which interprets only the first 8
bytes of the 16-byte timespec we hand it. With a little-endian layout
that means the legacy callee reads tv_sec = (low 32 bits of real tv_sec)
and tv_nsec = (high 32 bits of real tv_sec, normally 0). Sub-second
timeouts therefore become {0,0} and return immediately, while multi-
second timeouts get truncated to whole seconds.

That matches the test failure reported on armv7:

    /* test_simple_timeout */
    src/libsystemd/sd-event/test-event.c:724: Assertion failed:
      Expected "t >= usec_add(f, some_time)",
      but 571153514285 < 571154403965

(the 889680 us shortfall is consistent with a sub-second `some_time` that
got rounded down to zero by the truncated wait).

Fix it by adding a DEFINE_LIBC_ERRNO_SHIM_NAMED() variant of the macro
that takes an explicit dlsym symbol name string. Both macros keep their
own copy of the body so every `func` reference stays behind `#` or `##`,
otherwise the override-header `#define epoll_pwait2 epoll_pwait2_shim`
would rewrite the token before the inner macro could paste it (yielding
`epoll_pwait2_shim_shim`). src/libc/epoll.c then picks
"__epoll_pwait2_time64" under __USE_TIME_BITS64 so the cached function
pointer matches the timespec ABI the rest of the code is built with.

Follow-up for f795d54591

Co-developed-by: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-24 15:00:37 +02:00
Luca Boccassi 23d3d074ff base-filesystem: add powerpc ifdef branch 2026-05-24 13:34:31 +02:00
Luca Boccassi d61ce0c995 base-filesystem: add hppa ifdef branch 2026-05-24 13:34:31 +02:00