Commit Graph
61886 Commits
Author SHA1 Message Date
quanyeyang 5199e9618d sd-ndisc: stop solicitations only after an RS and non-zero-lifetime RA
RFC 4861 section 6.3.7 states that a host should send at least one Router
Solicitation even if it receives an unsolicited Router Advertisement
before sending its first solicitation, and should stop soliciting only
after receiving a valid Router Advertisement with a non-zero Router Lifetime.

Keep the RS timer active until both conditions are met, and add a
regression test for a zero-lifetime RA arriving before the initial RS.

Fixes #43205.
2026-09-10 11:53:44 +09:00
Chris Down 2ff84cf0a1 journalctl: Restore listing the whole catalog when no ID is given
The conversion to the OPTION macros in c3f4c1b8d6 ("journalctl:
convert to OPTION macros") replaced strv_copy_unless_empty() with
strv_copy().

This is problematic because the positional arguments are now an empty
strv rather than NULL when none are given, but `--{list,dump}-catalog`
rely on that.

Instead let's hand NULL back to them when there is nothing on the
command line.
2026-09-10 03:32:51 +09:00
Siteshwar Vashisht cef0631a8d btrfs-util: validate that sh.len is large enough
... to contain the `struct btrfs_chunk` header and all declared stripes
before using `num_stripes` as a loop bound.
2026-09-10 03:31:16 +09:00
Siteshwar Vashisht cdead3747f network/netdev: add a NULL check
... for `netdev->ifname`.
2026-09-10 01:00:04 +09:00
Totoro 951cfae10b creds: decode Base64 when reading encrypted credentials
Encrypted credentials produced by systemd-creds are stored as Base64.
Decode them before decrypting in read_credential_with_decryption(), while
leaving plaintext credentials unchanged and retaining their precedence.

Bound the decoded encrypted input and report oversized credentials
explicitly. Match the plaintext reader's string semantics by rejecting
embedded NUL bytes when no size output is requested, while preserving
binary payloads for callers that request their size.

Add regression coverage for missing and malformed credentials, plaintext
precedence, decoded size boundaries, single-line and wrapped Base64,
empty strings, and binary data. Keep test outputs and host secrets scoped
to private fixtures.

Fixes #43621
2026-09-10 00:20:09 +09:00
Yu Watanabe 6a68191199 compress: avoid shifting null pointer
Otherwise, UBSAN complains when src is NULL even though the shift is zero:

../src/basic/compress.c:2074:29: runtime error: applying zero offset to null pointer
2026-09-10 00:11:29 +09:00
Umut Tezduyar Lindskog 6175b6cb89 Align UEFI terminology
Also fix below:
“authenticode” → “Authenticode”
“implementend” → “implemented”
“next stage” → “next-stage” when used adjectivally.
2026-09-09 11:53:17 +02:00
Totoro c99616f2a3 json-stream: preserve split CRLF delimiters across reads
When a multi-byte delimiter straddles two reads, json_stream_parse()
only scans the bytes from the latest read. As a result, a QMP reply
whose "\r\n" terminator is split between reads is not recognized.

Include up to delimiter_size - 1 trailing bytes from the existing buffer
in the next scan, so delimiters spanning reads can be matched.

Add regression coverage for a split CRLF delimiter followed by another
message in the same read. Check that both objects are parsed correctly
and that no buffered input remains afterwards.
2026-09-09 10:53:25 +02:00
Lennart Poettering 59117e6a34 core: fix two cases where we pass incorrect errors to logging 2026-09-09 17:24:09 +09:00
Luca Boccassi 816d1e48cc include: update syscalls lists 2026-09-08 20:47:54 +01:00
Yu Watanabe e0577192d0 tar-util: fix error code on failure (#43688) 2026-09-09 04:27:38 +09:00
Zbigniew Jędrzejewski-Szmek bf3860292e udevadm: restore noop behaviour when udevd is not running
This partially reverts 17e911ffc8.
Previously 'udevadm settle' would silently succeed if udevd was not
reachable. Restore this behaviour.

C.f. https://forge.fedoraproject.org/releng/compose-tracker-issues/issues/9573.
2026-09-09 04:26:48 +09:00
Yu Watanabe 2170ce77f2 acl-util: make acl_set_perm() helper return negative errno
All callers expect it returns negative errno on failure.
2026-09-09 00:45:17 +09:00
Yu Watanabe f3a9444896 tar-util: fix error cause passed to logger 2026-09-09 00:45:17 +09:00
dongshengyuan e1ae3a43d3 sysupdate: display all component documentation URLs in table output
Component definitions may contain multiple Documentation= URLs, but the
components command previously displayed only the first URL in text output.

Use TABLE_STRV_WRAPPED to display all component documentation URLs in the
table, making the full documentation list visible to users.
Add integration test coverage for multiple Documentation= assignments.
2026-09-08 16:05:39 +02:00
dongshengyuan a6f7ded859 updatectl: fix feature JSON parsing
The feature JSON payload switched to `id`, `isEnabled`, and `appstream`,
and made `documentation` an array of URLs.
`updatectl` still parsed legacy table-derived names and a single URL.
This broke feature JSON parsing and made output inconsistent.
Features without documentation could also cause a null dereference.

Align `updatectl` with the current schema and preserve all
documentation URLs across sysupdate, D-Bus, and Varlink payloads.
Propagate condition evaluation errors through `condition_test_list()`
and `feature_is_suggested()`, with consistent JSON error handling and
tests.
The `suggested` field is now optional and always a boolean when
present; it is omitted rather than set to an error string when
SuggestOn*= conditions cannot be evaluated.
Add `suggested` metadata and document the field transition.

Follow-up for 3e34ccf6df.
Follow-up for 75a247d4de.
Follow-up for 40e727c93b.

Fixes #43603
2026-09-08 16:05:36 +02:00
dongshengyuan 8839a9810e condition: propagate errors from condition_test_list()
Make condition_test_list() return negative errno on condition
evaluation errors instead of coercing them to false. This allows
callers to distinguish between a condition that evaluated to false
and a condition that failed to evaluate.

Callers that only need a boolean result explicitly check for a
positive return value, preserving their current behavior.

Add comprehensive unit tests covering error propagation with trigger
and non-trigger conditions. Tests use uname_architecture() to get the
runtime architecture instead of native_architecture(), ensuring they
work correctly in environments where binaries run under architecture
emulation.
2026-09-08 17:34:06 +08:00
Siteshwar Vashisht 6df59b0753 tar-util: fix an off by one read
Standard Linux POSIX ACL tag values are 0x00, 0x01, 0x02, 0x04, 0x08,
0x10 and 0x20. ELEMENTSOF(tag_map) evaluates to 33, which is one past
the last valid index 32.
2026-09-08 14:34:47 +09:00
Michael Vogt 7efa326b7a sysext: use [] in json mode when giving the extension status
The json mode was returning the string `none` when unmerged and
an array for merged extensions. Return an empty array instead.

Instead of branching on the output format, always add an empty strv
for an unmerged hierarchy: the table code renders an empty strv as
the ersatz string ("-") in text mode and as an empty array in json
mode. This also changes the human-readable output from "none" to "-".

It also updated the TEST-50-DISSECT.sysext.sh test. Technically
this is a compatbility break but its also arguably a bugfix.
2026-09-07 18:29:25 +02:00
Luca Boccassi 548f87538a measure: expose offline signing data in policy-digest output
The PolicyPCR digest is not always the complete input to an offline
signature. PolicyAuthorize also includes the hashed policy reference.
This is now required for NVPCRs to work in the initrd.

Expose the complete data as "tbs" (to-be-signed) and use it when ukify
matches offline signatures. Keep "pol" as the compatibility fallback.

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

Follow-up for f0f3687700
2026-09-07 16:15:42 +01:00
Zbigniew Jędrzejewski-Szmek 7c447814ca network: update string tables (#43677) 2026-09-07 16:39:53 +02:00
zouge666 7d463c443a vmspawn: reject .mstack machine images gracefully
OCI pulls create .mstack machine images, which vmspawn can
discover via -M. Since vmspawn only supports directory and disk
images, this currently reaches assert_not_reached() and aborts.

Return EOPNOTSUPP with a readable error instead.

Fixes #41541
2026-09-07 15:06:30 +02:00
Yu Watanabe deef441b03 include: update kernel headers from v7.3-rc2
The only difference from the previous update is that now CONFIGFS_MAGIC
is listed in the magic.h, hence the override is not necessary anymore.
2026-09-07 19:36:29 +09:00
Yu Watanabe 5c7ca2d6a6 network: update route protocol string table
RTPROT_KEEPALIVED, RTPROT_OVN, and RTPROT_OPENR are added.
These are mostly used for logging, so documentation update is not
necessary.
2026-09-07 19:08:35 +09:00
Yu Watanabe 50a41d15b5 networkd-link: refactoring logger for IFF_ flags
No functional change.
2026-09-07 19:08:35 +09:00
Yu Watanabe 0b5d9bf140 wifi-util: update string tables
Note, NL80211_CMD_PROBE_CLIENT is renamed to NL80211_CMD_PROBE_PEER
in kernel v7.3:
https://github.com/torvalds/linux/commit/4ab9b637b94a3821acfcd6d6037dffe33669245a
2026-09-07 19:08:35 +09:00
Yu Watanabe 8577cfe2bc wifi-util: align table with = 2026-09-07 19:08:35 +09:00
Luca Boccassi cfca4412ca dns-packet: keep unreferenceable names out of the compression map (#43666)
Split out of https://github.com/systemd/systemd/pull/42983

## Problem
`dns_packet_append_name()` fails with `-EEXIST` once a name that was
first appended at an offset beyond RFC 1035's 14-bit compression-pointer
range (0x4000) occurs again in the same packet: the fall-through that
re-emits the labels trips `hashmap_ensure_put()` on the existing map
entry, and the whole packet build fails — reported by the caller as, for
example, "Failed to build reply packet: File exists".

The map is meant to hold only offsets a pointer can actually reference.
Names past that range were being inserted anyway, so they were dead
weight that could never be pointed at, and re-encountering one turned
into an error.

## Fix
Keep names at offsets ≥ 0x4000 out of the compression map entirely.
"Mapped implies referenceable" becomes an invariant of the map rather
than something callers have to reason about, and the `-EEXIST` collision
cannot arise. A re-occurrence of such a name is emitted as labels, still
compressed from the first suffix that *is* mapped in range — which is
the only encoding RFC 1035 section 4.1.4 permits in that case, since a
pointer must address ≤ 0x3FFF.

## Impact
Any packet large enough to push a name past 16KiB hits this — it is not
mDNS-specific, though that is where it was found: a DNS-SD announcement
covering a few hundred published services crosses the threshold easily,
and every record after it fails to encode.

## Test
`test-dns-packet-append` gains coverage for the boundary: a name first
written past the pointer range and then repeated, the same for a full
resource record, the rollback path when an append fails mid-name, and
the map invariant itself (asserted over the whole map, so a future
change that inserts an unreferenceable offset is caught rather than
silently reintroducing the bug).

## Testing status
Builds clean with `-Dwerror=true`; `meson test --suite resolve` passes
(19 ok, 1 skipped) at both commits.
2026-09-07 11:00:12 +01:00
Christian Glombek 21de179519 dns-packet: roll back the compression map when the root label fails
dns_packet_append_name() appends a name's labels and then the root byte
that terminates it. A failure on that last byte returned directly,
leaving both the labels on the packet and the compression entries this
call had added -- entries naming offsets the caller then truncates away.
Take the same rollback path as every other failure in the function.

Independent of the map invariant fixed before it: this is reachable
whether or not any offset exceeded the pointer range.
2026-09-07 04:26:36 +02:00
Christian Glombek a4b109f01f test: dns-packet: pin suffix compression past the pointer range
The existing case only covered a fully-uncompressed re-occurrence. Every
DNS-SD name shares an in-range suffix, so also pin that a name first
seen beyond the pointer range still compresses from its mapped suffix --
one label plus a two-byte pointer per occurrence, map unchanged, and the
pointer addressing the suffix's prior occurrence rather than any
in-range octet.

A padding helper puts the next append at a chosen offset, for the two
sides of the boundary: at 0x3FFF the name is still mapped and re-occurs
as a pointer whose wire bytes are checked independently of the parser;
one past it, it is not mapped.
2026-09-07 04:26:36 +02:00
Christian Glombek a95358da6f dns-packet: keep unreferenceable names out of the compression map
dns_packet_append_name() added every name it appends to the packet's
compression map, including names written at offsets >= 0x4000 that an
RFC 1035 compression pointer (14 bits) can never reference. Such
entries are not just useless -- when the same name occurs again, the
lookup finds it, the pointer cannot be emitted, the code falls through
to appending the labels again, and the re-insertion into the map then
fails the whole packet build with hashmap_ensure_put() returning
-EEXIST.

This is easily triggered with mDNS: an unsolicited DNS-SD announcement
covering a zone with a few hundred services exceeds 16KiB, and
dns_scope_announce() then fails with "Failed to build reply packet:
File exists".

This lifts the failure only: dns_scope_announce() still builds the whole
zone into one packet and hands it to the socket as a single datagram,
fragmented as the link requires. Splitting announcements across
MTU-sized packets, as RFC 6762 section 17 asks, is done separately.

Only insert a name into the map if its offset is pointer-expressible,
making "mapped implies referenceable" a map invariant. Re-occurrences of
out-of-range names are emitted as labels again -- the only encoding RFC
1035 section 4.1.4 permits in that case -- still compressed from the
first suffix that is mapped in range.

The lookup restates that range as control flow rather than asserting it.
Under -Db_ndebug=true, which CI builds, assert() is
__builtin_unreachable(), so an out-of-range entry would put 0xC000 | n
truncated to 14 bits on the wire -- a pointer to an arbitrary earlier
offset -- where falling through emits the labels instead. This layer is
shared with unicast DNS, DoT and LLMNR.

The pointer's tag bits and its offset bound are now named once, in
dns-def.h next to the other wire-format constants rather than in
dns-packet.h, since the format is RFC 1035's and not this packet
abstraction's -- dhcp-message.c open-codes the same two bits to parse
compressed names out of DHCP options. Compile-time checks pin that the
two partition the 16-bit field and that the tag is its top two bits,
which is what lets the reader take it from the first octet alone.

The offset's other bound becomes control flow along with it: it was an
assert(), which under -Db_ndebug=true is no check at all, for the bound
whose violation puts a pointer to the wrong bytes on the wire. It is
also tightened to the start of the name being appended rather than the
end of the packet, which is the "prior occurrence" RFC 1035 section
4.1.4 allows a pointer to address and what dns_packet_read_name()
enforces on the way in.

Add regression tests, including one through dns_packet_append_rr() --
the path the reported failure came from, where the name append is nested
inside the rdlength backpatch and two further rollbacks -- and one for
the reader's label-type dispatch, which the renamed constants touch.
2026-09-07 04:26:33 +02:00
Luca Boccassi bc17a73107 core: don't exit 0 when a failure action has nothing to propagate (#43647)
Fixes #43645.

`FailureAction=exit` propagates the exit status of the unit's main
process. When there is none, `emergency_action()` left `m->return_value`
at its initial 0, so the manager exited 0 for a unit that failed —
indistinguishable from an orderly shutdown to whoever supervises it.
2026-09-05 11:54:29 +01:00
Totoro f789245918 machine: preserve read-only clone mode for foreign UID images
machinectl clone --read-only ignored the requested read-only mode when
cloning a foreign-UID-owned directory because the unprivileged clone path
did not receive the read_only argument.

Pass the flag through and apply the immutable bit via the already-open
destination directory fd after copying. Keep this best-effort, matching
the ordinary directory clone fallback, so failure to set the attribute
does not turn a completed copy into a reported clone failure.

Add a regression test using foreign-0 rather than a fixed UID. Verify
the cloned image's ReadOnly property, copied contents and ownership, and
that the immutable directory rejects new entries. Run this subtest only
when file attributes and the existing rootless nspawn prerequisites are
available, leaving the other machined tests unchanged.
2026-09-05 08:34:55 +02:00
Totoro 0c8f57cae2 machine: propagate foreign image clone directory errors
unprivileged_clone() returns success when mountfsd_make_directory() fails.
Consequently, callers can report a successful clone even though the
destination directory was never created.

Return the original error instead of zero so the failed clone is
reported to the caller.

Add a regression test that places a regular file without an image suffix
at the destination path. Such a file is ignored by image discovery but
prevents directory creation. Check that cloning reports failure without
changing the file, then succeeds after the conflicting file is removed.
2026-09-05 08:32:02 +02:00
Michael Renner 101b8633c2 journal: recover iteration over vacuumed files (#43649)
Vacuuming unlinks and deallocates archived journal files. A reader
may have already selected an entry from such a file, so final
validation can fail after candidate selection succeeded.

If the selected file is now unlinked, remove it and retry candidate
selection. Preserve errors from linked files, including the EIO
reported after SIGBUS recovery from a truncated mapping.
2026-09-05 11:17:59 +09:00
Yu Watanabe 0b5c330d15 Several follow-ups for wildcard hostname (#43628) 2026-09-04 17:39:51 +09:00
Totoro f4a7117af2 network: honor --root= for picked up credentials
network-generator writes generated command line configuration below
the alternate root passed with --root=, but network.* credentials
were copied to fixed host /run paths.

Build the credential target directories with arg_root before passing
them to pick_up_credentials(). This keeps normal boot behavior
unchanged while making credential output land in the requested root.
2026-09-04 14:22:25 +09:00
Armaan Sandhu 4a25049a9e resolved: don't disable the listening socket when a datagram is dropped
manager_recv() sizes its buffer with next_datagram_size_fd(), which peeks at
the datagram with MSG_PEEK|MSG_TRUNC. That peek makes the kernel verify the UDP
checksum - which is the whole point of using it over FIONREAD - and hence also
drop the datagram when the checksum is bad. The datagram that woke the event
source can thus be gone by the time we peek at it, and the peek returns EAGAIN.

manager_recv() returned that error, while the recvmsg_safe() below, which can
fail the same way, already treats it as "no packet". The callers on the mDNS,
LLMNR and stub listening sockets pass a negative return on to the event loop,
which disables the event source, so a single datagram with a bad checksum -
something anyone on the link can send - stops resolved from receiving on that
socket for good. on_dns_packet() completes the transaction with -EAGAIN instead
of retrying it.

So return 0 on a transient error here too, like the other users of the helper
on an event source do. Disconnect errors are left as they are: they show up
here from ICMP errors on the connected UDP socket, and on_dns_packet() handles
them.
2026-09-04 13:53:04 +09:00
Yu Watanabe 175b52e294 network-generator: use parse_path_argument() to avoid spurious paths 2026-09-04 11:26:11 +09:00
Yu Watanabe c21a49cd3d core/swap: don't resurrect swap units whose device link disappeared (#43443)
Fixes #43442.

A `.swap` unit can end up **active but unloadable, with no device**, and
stopping such a unit aborts PID 1.

### What it looks like

```
$ systemctl show 'dev-disk-byx2dpartlabel-primary.swap' -p LoadState,ActiveState,What
LoadState=not-found
ActiveState=active
What=                     # <-- no device

$ systemctl stop 'dev-disk-byx2dpartlabel-primary.swap'
systemd[1]: About to execute: /usr/sbin/swapoff        # <-- no argument
systemd[1]: Caught <ABRT>, from our own process.
systemd[1]: Freezing execution.
```

PID 1 stays alive but frozen, so the machine stops answering `systemctl`
and never reboots.

### How it happens
1. systemd creates one `.swap` unit per udev device link of every device
in `/proc/swaps`.
2. A device link gets repointed at another device while the swap stays
on. `/proc/swaps` doesn't change, so nothing re-examines the unit — it
stays active.
3. The next `daemon-reload` drops all units and rebuilds them.
Enumeration from `/proc/swaps` no longer produces this name, so only the
deserialization brings the unit back: by name, with no fragment on disk.
4. `swap_load()` only calls `swap_add_extras()` for units that loaded a
fragment or are backed by `/proc/swaps`, so this one gets neither a
`What=` nor a patched `ExecContext`.
5. `swap_coldplug()` restores its active state anyway.
6. Shutdown stops it. `unit_stop()` deliberately permits stopping units
whose load failed, so it reaches `exec_spawn()` and trips the
`PrivateVarTmp=` assertion in `exec_context_serialize()`.
2026-09-04 04:11:29 +09:00
Siteshwar Vashisht 504ebbe826 creds-util: add a check in decrypting credentials
... and avoid continuing decryption in case of failure.
2026-09-04 03:29:27 +09:00
Siteshwar Vashisht b4f2262be8 journal: fix cleaning up iovec entries
... when journald's messages exceed `kmsg_own_ratelimit`.
2026-09-04 03:29:00 +09:00
Ivan Kruglov 566436f1c6 core: don't exit 0 when a failure action has nothing to propagate
FailureAction=exit propagates the exit status of the unit's main process. When
there is none, emergency_action() left m->return_value at its initial 0, so the
manager exited 0 for a unit that failed. Whoever supervises it, e.g. a container
manager, then can't tell this apart from an orderly shutdown.

There is no status to propagate whenever the unit type has no notion of a main
process (only .service has), or the unit failed before any of its processes ran,
say because its cgroup couldn't be created. StartLimitAction= and
JobTimeoutAction= never have one at all.

Fixes: https://github.com/systemd/systemd/issues/43645
2026-09-03 10:09:32 -07:00
Ivan Kruglov d4b6e74655 core: use EXIT_EXCEPTION instead of a bare 255
No functional change.
2026-09-03 10:09:02 -07:00
Luca Boccassi 8cceaab8f5 ukify: generate initrd policy digests for offline signing
When --sign-initrd-pcrs is used with --policy-digest, generate the
extra enter-initrd policy with the "initrd" policy reference. This
matches the policy produced when ukify signs with a private key.

Fixes building UKIs with offline signing (e.g.: on OBS) and using
NVPCRs.

Follow-up for f0f3687700
2026-09-03 12:55:15 +02:00
nl6720 786fcb493f networkd: allow systemd-network user to control ModemManager
systemd-networkd needs authorization for
`org.freedesktop.ModemManager1.Device.Control` to allow establishing a
connection:

    systemd-networkd[1457]: ModemManager: starting simple connect on huawei E3276 interface wwp106s0u4i2
    systemd-networkd[1457]: Could not connect modem huawei E3276: Unauthorized: PolicyKit authorization failed: not authorized for 'org.freedesktop.ModemManager1.Device.Control'
2026-09-03 18:05:17 +09:00
Yu Watanabe d028295865 hostname-setup: use READ_FULL_FILE_VERIFY_REGULAR 2026-09-03 06:56:54 +09:00
Yu Watanabe 65a967fc46 test: several follow-ups for test-hostname-pick-word
'pos' must be >= 1, otherwise triggers assertion in
hostname_pick_word().
'c' should be >= 1, otherwise nothing tested.
2026-09-03 06:45:43 +09:00
Armaan Sandhu 2451b1a9c4 resolve: fix use-after-free of the service browser in mDNS maintenance
mdns_maintenance_query_complete() takes a reference on
query->dnsservice_request and never drops it, so every successful mDNS
maintenance query leaks one reference to the discovered service.

The leak alone would be benign, but the service owns the one-shot event
source that drives its maintenance schedule, and it only borrows a plain
pointer to its service browser. Once the extra reference is outstanding,
dns_service_browser_free() -> dns_remove_service() only drops the list's
reference, so dns_service_free() never runs, the maintenance timer is
never disabled, and the service outlives the browser it points at. The
next time the timer fires, mdns_maintenance_query() dereferences the
freed DnsServiceBrowser to reach the manager's event loop and to issue
the query.

Reaching it only takes a browse subscription whose record lives long
enough for one maintenance query to be answered, followed by the
subscription going away.

Make the reference a _cleanup_ one, the way the sibling
mdns_browse_service_query_complete() below already handles the reference
it takes on the service browser.
2026-09-03 06:37:53 +09:00
Yu Watanabe 15f7905335 Tweak the hostname-worldlist code (#43599) 2026-09-03 06:29:25 +09:00