pcrlock: don't accept PCRs > 23 from firmware event log
Let's harden ourselves against shitty firmware which might report an
invalid PCR.
(This is not really a security issue, more a robustness issue, after all
firmware generally comes with highest privileges and trust, even though
it might just be shit)
Ivan Kruglov [Thu, 12 Mar 2026 12:14:40 +0000 (05:14 -0700)]
test: use --nogpgcheck instead of --no-gpgchecks in TEST-88-UPGRADE
--no-gpgchecks was introduced in 920483872449 but is only available in
dnf5. Use --nogpgcheck instead, which is supported by both dnf4 and
dnf5 (where it is an alias for --no-gpgchecks).
Fixes test failure on distros still using dnf4 (e.g. CentOS/RHEL 9).
Fix text overflow for long URLs and inline code blocks (#41064)
## Summary
Long string URLs and inline code blocks can exceed page width and cause
horizontal scroll overflow that breaks page layouts on smaller screens.
This fix ensures those long strings can wrap down as needed to preserve
the layout. The only code blocks that are affected are those that are
inline span within text paragraphs and are effectively stylized text; it
does not affect `<pre>` code blocks where fidelity is prioritized and
contained horizontal scroll is preferred.
Luca Boccassi [Wed, 11 Mar 2026 19:40:43 +0000 (19:40 +0000)]
core: limit number of LogExtraFields (#41044)
We have two places where those fields can be set: config and the dbus
interface. Let's clamp down on the number in both places. But in
principle, we could also be upgrading (through
serialization/deserialization) from an older systemd which didn't
enforce this limit, so also check on deserialization. A user could have
a unit with lots and lots of ExtraFields, but not enough to cause the
issue in #40916. To handle this gracefully, ignore the extra fields,
like we do in the parser. Where the field is used, assert that we are
within the expected bounds.
Fixes #40916.
Reproducer:
```console
$ python3 -c 'from pydbus import SystemBus; from gi.repository import GLib; SystemBus().get("org.freedesktop.systemd1", "/org/freedesktop/systemd1").StartTransientUnit("crash.service", "fail", [("ExecStart", GLib.Variant("a(sasb)", [("/bin/true", ["/bin/true"], False)])), ("LogExtraFields", GLib.Variant("aay", [b"F%d=x" % i for i in range(140000)]))], [])' Traceback (most recent call last):
File "<string>", line 1, in <module>
from pydbus import SystemBus; from gi.repository import GLib; SystemBus().get("org.freedesktop.systemd1", "/org/freedesktop/systemd1").StartTransientUnit("crash.service", "fail", [("ExecStart", GLib.Variant("a(sasb)", [("/bin/true", ["/bin/true"], False)])), ("LogExtraFields", GLib.Variant("aay", [b"F%d=x" % i for i in range(140000)]))], [])
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.14/site-packages/pydbus/proxy_method.py", line 102, in __call__
raise error
File "/usr/lib/python3.14/site-packages/pydbus/proxy_method.py", line 97, in __call__
result = instance._bus.con.call_sync(*call_args)
gi.repository.GLib.GError: g-dbus-error-quark: GDBus.Error:org.freedesktop.DBus.Error.InvalidArgs: Too many extra log fields. (16)
```
We have two places where those fields can be set: config and the dbus
interface. Let's clamp down on the number in both places. But in principle, we
could also be upgrading (through serialization/deserialization) from an older
systemd which didn't enforce this limit, so also check on deserialization. A
user could have a unit with lots and lots of ExtraFields, but not enough to
cause the issue in #40916. To handle this gracefully, ignore the extra fields,
like we do in the parser. Where the field is used, assert that we are within
the expected bounds.
Fixes #40916.
Reproducer:
$ python3 -c 'from pydbus import SystemBus; from gi.repository import GLib; SystemBus().get("org.freedesktop.systemd1", "/org/freedesktop/systemd1").StartTransientUnit("crash.service", "fail", [("ExecStart", GLib.Variant("a(sasb)", [("/bin/true", ["/bin/true"], False)])), ("LogExtraFields", GLib.Variant("aay", [b"F%d=x" % i for i in range(140000)]))], [])'
Traceback (most recent call last):
File "<string>", line 1, in <module>
from pydbus import SystemBus; from gi.repository import GLib; SystemBus().get("org.freedesktop.systemd1", "/org/freedesktop/systemd1").StartTransientUnit("crash.service", "fail", [("ExecStart", GLib.Variant("a(sasb)", [("/bin/true", ["/bin/true"], False)])), ("LogExtraFields", GLib.Variant("aay", [b"F%d=x" % i for i in range(140000)]))], [])
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "/usr/lib/python3.14/site-packages/pydbus/proxy_method.py", line 102, in __call__
raise error
File "/usr/lib/python3.14/site-packages/pydbus/proxy_method.py", line 97, in __call__
result = instance._bus.con.call_sync(*call_args)
gi.repository.GLib.GError: g-dbus-error-quark: GDBus.Error:org.freedesktop.DBus.Error.InvalidArgs: Too many extra log fields. (16)
udev-builtin-net-id: print cescaped bad attributes
Follow-up for 16325b35fa6ecb25f66534a562583ce3b96d52f3. Let's
log those bad value to make it easier to figure out why things
are not working if we reject an attribute.
Dylan M. Taylor [Fri, 6 Mar 2026 15:05:32 +0000 (10:05 -0500)]
userdb: mark PII fields as sensitive in user records
Mark realName, emailAddress, and location as sensitive in JSON user
records so that they are excluded from debug log output. These fields
contain personally identifiable information that should not be leaked
in logs, which are generally more accessible than the user database
itself.
Yu Watanabe [Mon, 9 Mar 2026 06:18:24 +0000 (15:18 +0900)]
sd-dhcp-client: several fixlets for sending RELEASE or DECLINE
- Extract common logic to client_send_release_or_decline().
- Do not send DECLINE message on BOOTP protocol.
- Drop redundant assignment of chaddr, as it is already set by
client_message_init() -> dhcp_message_init().
- Do not assign acquired address in ciaddr field of DECLINE message,
but use Requested IP Address option.
- Broadcast DECLINE message, rather than unicast.
- Set server identifier in both cases.
Rodrigo Campos [Fri, 6 Mar 2026 15:54:02 +0000 (16:54 +0100)]
dissect: Don't bypass blkid *_lookup_value() to decide USAGE
After commit "core: reuse existing dm-verity device for single
filesystem images pinned by policy" (0bd766553cbf), when I attach a
portable image (erofs+verity) and try to start a service, it fails with:
Partition root discovered with policy 'unprotected' but 'verity+read-only-on+growfs-off+erofs' was required, refusing.
Failed to dissect image: Operation not possible due to RF-kill
The image does have verity, in fact the RootImagePolicy= field was added
automatically.
The inconsistency between what is found at attach vs when starting the
service comes from the fact that dissect_image() is called with a
different policy as parameter and the recent shortcut added.
At attach we do this:
dissect_image(policy="*")
partition_policy_determine_fstype(policy)
partition_policy_flags_to_string(...) // mask is 0, returns 0
-> returns NULL // root_fstype_string is not set
if (root_fstype_string) // false
sym_blkid_probe_lookup_value()...
At start, as we do have the policy set, we do:
dissect_image(policy="root=verity+...+erofs:root-verity=...")
partition_policy_determine_fstype(policy)
partition_policy_flags_to_string(...) // returns 1
-> sets root_fstype_string to "erofs"
if (root_fstype_string) // true
usage = "filesystem"
Then, the service is blocked to start with the aforementioned error.
It's correct for partition_policy_determine_fstype() to set erofs in
that case, and other callers seem to expect this behavior on similar
cases, but what is not correct is to assume that this means it's a
filesystem. Usage in this case should still be unset.
Let's just always do the lookup, as that gets us the correct answer reliably
and we already did the slow part that is the probe.
The call to `sym_blkid_do_safeprobe()` is a few lines above. The call to
the lookup function isn't very expensive. blkid_probe_lookup_value()[1]
calls __blkid_probe_lookup_value(), which searches on a list[2], IIUC in
memory and no IO is used. It's a linear search of the property.
Daan De Meyer [Tue, 10 Mar 2026 18:57:11 +0000 (19:57 +0100)]
ci: Don't make a single failed review comment fail the entire job
Let's handle failure to post individual review comments gracefully.
Reduces the impact of failures like in
https://github.com/systemd/systemd/actions/runs/22904601370/job/66461528144.
bus_cgroup_set_tasks_max_scale() used a hand-rolled percentage format
that produced values ~10x too small (e.g., "TasksMax=4.0%" instead of
"TasksMax=40.00%").
On daemon-reload, the incorrect value was re-read, silently reducing
the effective TasksMax by ~10x and causing fork rejections on systems
with high thread counts.
Fix by using the existing PERMYRIAD macros, consistent with memory
property handlers (MemoryMax, MemoryHigh, MemoryLow, etc.).
Luca Boccassi [Tue, 10 Mar 2026 17:55:43 +0000 (17:55 +0000)]
Translations update from Fedora Weblate (#41021)
Translations update from [Fedora
Weblate](https://translate.fedoraproject.org) for
[systemd/main](https://translate.fedoraproject.org/projects/systemd/main/).
networkd: fix for networkd crash when client sends Option 82 via SendOption=
When a DHCP client uses SendOption=82:string:..., option_append() calls
the SD_DHCP_OPTION_RELAY_AGENT_INFORMATION case which was written for
the server relay path. It casts optval to sd_dhcp_server* and calls
strlen() on its members, but optval is actually raw binary data from
the client, causing SIGSEGV. The same is applicable when option 43 and
option 77 are passed to SendOption.
Fix by checking optlen > 0 and appending the option as a plain TLV,
skipping the server-specific relay agent logic.
Luca Boccassi [Mon, 9 Mar 2026 11:25:50 +0000 (11:25 +0000)]
nsresourced: downgrade benign log message to debug
This is very noisy as there's a dozen of these message every
time it gets called, and it's not really an error but an
expected situation, so downgrade from info to debug
* 56e0eed69a Update changelog for 260~rc2-1 release
* 36e6a6d247 Install new files
* 692d0ffde5 Install new files for upstream build
* 04e77a9300 Enable getty@ via packaging scriptlets, not static anymore
* 65e7898ab5 Remove build-depend on rsync, meson is new enough
* 1ab5e82a93 Update changelog for 260~rc1-2 release
* 17a8004c53 sd-boot-efi: do not pick up hwids, they are shipped by sd-ukify
* b620f379b3 Update changelog for 260~rc1-1 release
* 8eb95fc404 Drop unused Lintian overrides
* 82a111e7ef Update symbols file for v260~rc1
* 9cb8e0457b Disable remaining deprecated sysv interfaces
* 100d97ba82 Install new files for v260~rc1
* b8e9e50f4d initramfs-tools: copy udev link files from /usr/local/lib/systemd/network too
Yu Watanabe [Tue, 10 Mar 2026 00:18:48 +0000 (09:18 +0900)]
semaphore: use Ubuntu 24.04
Semaphore CI/CD now emits the following error.
```
OS image 'ubuntu2004' for machine type 'e1-standard-2' is currently in a brownout phase.
Please use another OS image.
```
Let's use newer image.
Yu Watanabe [Mon, 9 Mar 2026 04:24:03 +0000 (13:24 +0900)]
sd-device: refuse spurious properties
Properties are set through uevent, udev rules, or program output by IMPORT.
They may contain spurious characters and udev database parsers may be confused.
Let's refuse spurious properties.
When using systemd-mount to create a transient .mount/.automount file
for removable storage, the option to specify the idle timeout on the
commandline using **--timeout-idle-sec=SEC** is not reflected in the
generated .automount file. Instead, the idle timeout is always set to 1
second.
arg_timeout_idle_set was never set to true when passing the argument, so
arg_timeout_idle was always set to 1s.
Daan De Meyer [Mon, 9 Mar 2026 09:33:20 +0000 (10:33 +0100)]
ci: Don't cancel in progress jobs for claude-review workflow
This workflow runs on any comment to a github PR. 99% of the time the
workflow will be skipped yet it will still cancel any previous ongoing
workflows. Let's not cancel in progress workflow but instead queue the
workflow so we don't cancel in progress reviews any time a comment is
posted on a PR that is being reviewed.
Daan De Meyer [Fri, 6 Mar 2026 14:58:06 +0000 (15:58 +0100)]
ci: privilege-separate Claude review workflow
The workflow is split into two jobs for least-privilege:
1. 'review' job — runs Claude with read-only permissions (contents: read,
id-token: write for AWS OIDC, actions: read). Claude produces a structured
JSON review via --json-schema with a 'comments' array and a 'summary'
string. Its tools are restricted to read-only operations (Read, LS, Grep,
Glob, Task, and various Bash prefixes for common read-only commands).
Claude also has access to CI MCP tools to analyze failed workflow runs.
2. 'post' job — only has pull-requests: write. Reads the structured JSON
output from the review job and posts inline comments individually (so
re-runs only add new comments). Maintains a tracking comment with a
<!-- claude-pr-review --> marker that is created on first run and updated
in-place on subsequent runs, preserving existing item order, wording,
and checkbox state. Posts a notification comment when the tracking
comment is updated or left unchanged.
Comment deduplication is handled by Claude in the prompt rather than in
the posting script, allowing for better semantic understanding of whether
two comments address the same issue.
The PR number is resolved via github.event.pull_request.number with a
fallback to github.event.issue.number for issue_comment events where
github.event.pull_request is not populated. The concurrency group uses
the same fallback.
Yu Watanabe [Mon, 9 Mar 2026 02:46:01 +0000 (11:46 +0900)]
network: route bound to a link requires the link is up
We checked if the link is up only when configuring (explicit) nexthop,
but we did not checked that when configuring route which has (implicit)
nexthop.
Let's move the checks from nexthop_is_ready_to_configure() to
gateway_is_ready(), which is called for both implicit and explict
nexthops.
Yu Watanabe [Mon, 9 Mar 2026 02:30:54 +0000 (11:30 +0900)]
network: check if gateway is ready only when the nexthop is bound to link
Currently, we support three types of nexthop:
1. simple nexthop, which is bound to link, may have specific gateway
address,
2. blackhole nexthop, which is global configuration and is not bound to
any links,
3. group nexthop, which is also global configuration and is not bound to
any links.
Thus, gateway_is_ready() is only necessary to call for simple nexthop
case. Let's make the logic simpler.
Luca Boccassi [Sat, 7 Mar 2026 10:55:42 +0000 (10:55 +0000)]
Translations update from Fedora Weblate (#40984)
Translations update from [Fedora
Weblate](https://translate.fedoraproject.org) for
[systemd/main](https://translate.fedoraproject.org/projects/systemd/main/).