Commit Graph

90932 Commits

Author SHA1 Message Date
lzwind
855285b07e hwdb: fix Lenovo B570e touchpad ABS ranges for edge scrolling (#43264)
The Lenovo B570e touchpad (ETPS/2 Elantech) reports ABS ranges that
are too wide by default, which makes edge scrolling trigger across
roughly the right half of the touchpad instead of only at the right
edge. Add an evdev hwdb entry in `60-evdev.hwdb` that overrides the
ABS_X/ABS_Y (and the matching MT position) ranges with the calibrated
values, following the same pattern already used for the Lenovo B590
and L430 entries.

Fixes #29666
2026-08-03 13:43:45 +09:00
lzwind
bee944044f hwdb: mark Adesso wireless keyboard trackball as trackball (#43263)
The Adesso wireless keyboard with an integrated trackball (MosArt
062a:4101) is identified as a regular mouse, so trackball-style
scrolling does not work out of the box. Add a hwdb entry in
`70-mouse.hwdb` setting `ID_INPUT_TRACKBALL=1` so libinput and other
clients treat the device as a trackball.

Fixes #29609
2026-08-03 13:42:13 +09:00
lzwind
d13c07ecd8 hwdb: mark Microsoft Surface Type Cover touchpad as internal (#43262)
The Microsoft Surface Type Cover touchpad (USB 045E:09C0) is attached
through a USB port that firmware reports as removable. Because of that,
`65-integration.rules` sets `ID_INPUT_TOUCHPAD_INTEGRATION=external`,
and libinput skips disable-while-typing (DWT) for the device.

The touchpad is physically integrated into the Type Cover, so add a hwdb
entry in `70-touchpad.hwdb` that overrides
`ID_INPUT_TOUCHPAD_INTEGRATION=internal`, restoring DWT.

Fixes #43256
2026-08-03 13:41:02 +09:00
Yu Watanabe
ac33190d1f include: update kernel headers from v7.2-rc5
It seems there is no notable changes to us.
2026-08-02 22:06:40 +09:00
dongshengyuan
78238fd7c9 socket: parse message queue size as IEC size
Allow MessageQueueMessageSize= to accept IEC size suffixes in socket unit files.
Support the same syntax for transient property assignments.
Keep MessageQueueMaxMessages= as a plain message count.
2026-08-02 19:17:51 +09:00
dongshengyuan
3bb3c54f3d sd-id128: parse UUID URNs
Accept RFC4122 UUID URN strings with the `urn:uuid:` prefix in
sd_id128_from_string(), while keeping plain 128-bit IDs and regular
UUID strings working as before.
2026-08-02 19:17:03 +09:00
dongshengyuan
574eed3b0d udevadm: improve symlink query output
Implement the TODO item for `udevadm info -q symlink`: keep the
default space-separated output pager-free, and make `--value` print
one symlink per line with an empty separator line between devices.
2026-08-02 19:16:19 +09:00
Frantisek Sumsal
56d2162bff po: resynchronize translations on Weblate
Weblate got itself into a conflict and while resolving it it forced a
resynchronization of all translations, which in combination with a new
version of Weblate triggered a lot of rather pointless
multiline-to-singleline (and vice versa) changes. Let's squash all this
noise into a single commit to make both Weblate and us happy.

C.f. https://github.com/systemd/systemd/pull/43248.
2026-08-02 16:54:09 +09:00
Paul Meyer
156fb14b6a report: replace boolean --sign with signing modes
Turn --sign=BOOL into --sign=no|best-effort|require-one|require-all,
making the multi-signer aggregation policy explicit: best-effort never
fails on signing, require-one requires at least one signature, and
require-all requires every signer to succeed (an empty reply, i.e. a
signer opting out, counts as failure). Signed reports are always emitted
as a JSON-SEQ stream. The mode is also exposed as an input to the
io.systemd.Report.GenerateSigned Varlink method.

Signed-off-by: Paul Meyer <katexochen0@gmail.com>
2026-08-02 15:13:35 +09:00
Eric Boucher
bc9870a923 sd-json: encode pidref fd_id as unsigned
PidRef.fd_id is uint64_t.
2026-08-02 14:14:46 +09:00
Zbigniew Jędrzejewski-Szmek
9eee40e687 selinux: alternate root support (#42768)
This PR changes some SELinux bits related to working with alternate
roots (specifically when using `--root` or `--image` on a bunch of
executables).

It addresses bug #42643 and it's hopefully the more whole approach than
the naive approach I PR'ed in #42644.

Before this PR the 'wrong' labels get applied because the path lookups
in the SELinux label database are prefixed with whatever the location of
the alternate root is (explained in more detail below).

Initially I had taken a very naive approach that did fix the issue by
stripping the alternate root from the path; however this still looks up
that path in the hosts' label database, which might differ from the one
contained in the alternate root.

So this expanded approach actually reads the label database from the
alternate root, strips the prefix *if* an alternate root is used
directly in `selinux-util.c` and then uses that to assign labels
instead.

See under the line for the behavior pre/post.

I've tried builds of this PR on both enforcing/non-enforcing/non-enabled
hosts *and* on enabled/non-enabled disk images and things seem to work
or at least fall back to ignoring MAC when required bits aren't present.

One thing is *if* an `/etc/selinux/config` is present that defines a
`SELINUXTYPE=` we *do* require the policy given to be present in the
image. This is the only new actual error in this code path that doesn't
get ignored.

We *could* verify that the path exists and also ignore it but I
personally don't think that's the right approach since the actual system
itself would likely also be broken anyhow. Let me know thoughts on that.

There's a tight coupling here still with the *hosts* SELinux policy in
that to set (potentially) unknown labels to the policy loaded in the
host kernel these executables would need to execute in a domain that
allows transitioning to `mac_admin`. I'd say that `install_t` is the
most likely candidate for that. See the first comment on this PR for
more explanation on it/request for input.

---

When mounting `a.raw` before running any tooling against it and showing
the `/etc/shadow` file labels we have:

```
€ sudo systemd-dissect --mount test/a.raw test/mnt/a
€ ls -Zlart test/mnt/a/etc/shadow
----------. 1 root root system_u:object_r:shadow_t:s0 520 Jun 27 07:55 test/mnt/a/etc/shadow
€ sudo systemd-dissect ---umount test/mnt/a
```

After running `systemd-firstboot` against the image, then remounting,
note the labels that have been changed to incorrect values:

```
€ sudo systemd-firstboot --image test/a.raw --root-password test    
/home/user/src/github.com/teamsbc/artifacts/test/a.raw: /etc/passwd written.
/home/user/src/github.com/teamsbc/artifacts/test/a.raw: /etc/shadow written.
€ sudo systemd-dissect --mount test/a.raw test/mnt/a           
€ ls -Zlart test/mnt/a/etc/shadow
----------. 1 root root system_u:object_r:init_var_run_t:s0 579 Jun 27 08:01 test/mnt/a/etc/shadow
```

The behavior before this PR looks up the labels in the label database of
the host, but the path that gets looked up is the path where the image
is temporarily mounted, or in the case of `--root` where the root is on
the host. Since that path doesn't define any labels we get the labels of
the location where the file was created on the host. In this case since
`--image` was used, which mounted things in a temporary location we end
up with `var_run_t`.

If this image is booted things that want to read `/etc/shadow` might not
be allowed to read files labeled this way; thus services fail to start,
and root can't login when SELinux is in enforcing mode.

After this PR is applied there are two main differences in how things
are handled. The first being that instead of reading the label database
from the host (which might have none, or have a different one from the
one contained inside an image or root) we read the label database from
inside the alternate root. This tries to make sure we get the correct
labels for given paths.

Second, and most importantly, if we did init SELinux with an alternate
root then any paths passed to the relevant label lookup functions strip
that alternate root from the path. While previously we'd look up a path
like `/run/dissect-XXXX/etc/shadow` we now look up a path like
`/etc/shadow` *and* this path gets looked up in the label database in
the alternate root.

Together these things give in my opinion better handling of SELinux in
alternate roots. To confirm things work here's the same operations on
the second copy of our image:

```
€ sudo systemd-dissect --mount test/b.raw test/mnt/b
artifacts € ls -Zlart test/mnt/b/etc/shadow
----------. 1 root root system_u:object_r:shadow_t:s0 520 Jun 27 07:55 test/mnt/b/etc/shadow
€ sudo ~/src/github.com/systemd/systemd/build/systemd-firstboot --image test/b.raw --root-password test
/home/user/src/github.com/teamsbc/artifacts/test/b.raw: /etc/passwd written.
/home/user/src/github.com/teamsbc/artifacts/test/b.raw: /etc/shadow written.
€ sudo systemd-dissect --mount test/b.raw test/mnt/b                                                  
€ ls -Zlart test/mnt/b/etc/shadow
----------. 1 root root system_u:object_r:shadow_t:s0 579 Jun 27 08:44 test/mnt/b/etc/shadow
```

Showing that we now have the correct labels applied.
2026-08-02 02:06:12 +02:00
Chris Down
7ce93b7fe0 properties: Skip unnecessary per property filtering (#43146)
In total this can save ~18% CPU on `systemctl show` nominal queries in
my tests.
2026-08-01 13:30:59 -07:00
Andrei Stepanov
324a96761e po: Translated using Weblate (Russian)
Currently translated at 100.0% (286 of 286 strings)

Co-authored-by: Andrei Stepanov <adem4ik@gmail.com>
Translate-URL: https://translate.fedoraproject.org/projects/systemd/main/ru/
Translation: systemd/main

[zjs: made some small corrections based on Claude comments.]
2026-08-01 19:24:33 +01:00
dependabot[bot]
70a180a490 build(deps): bump the actions group with 6 updates
Bumps the actions group with 6 updates:

| Package | From | To |
| --- | --- | --- |
| [actions/checkout](https://github.com/actions/checkout) | `7.0.0` | `7.0.1` |
| [actions/setup-python](https://github.com/actions/setup-python) | `6.3.0` | `7.0.0` |
| [github/codeql-action/upload-sarif](https://github.com/github/codeql-action) | `4.36.2` | `4.37.3` |
| [aws-actions/configure-aws-credentials](https://github.com/aws-actions/configure-aws-credentials) | `6.2.0` | `6.2.3` |
| [softprops/action-gh-release](https://github.com/softprops/action-gh-release) | `3.0.1` | `3.0.2` |
| [ossf/scorecard-action](https://github.com/ossf/scorecard-action) | `2.4.3` | `2.4.4` |


Updates `actions/checkout` from 7.0.0 to 7.0.1
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](9c091bb21b...3d3c42e5aa)

Updates `actions/setup-python` from 6.3.0 to 7.0.0
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](ece7cb06ca...5fda3b95a4)

Updates `github/codeql-action/upload-sarif` from 4.36.2 to 4.37.3
- [Release notes](https://github.com/github/codeql-action/releases)
- [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md)
- [Commits](8aad20d150...e4fba868fa)

Updates `aws-actions/configure-aws-credentials` from 6.2.0 to 6.2.3
- [Release notes](https://github.com/aws-actions/configure-aws-credentials/releases)
- [Changelog](https://github.com/aws-actions/configure-aws-credentials/blob/main/CHANGELOG.md)
- [Commits](e7f100cf4c...e6de054238)

Updates `softprops/action-gh-release` from 3.0.1 to 3.0.2
- [Release notes](https://github.com/softprops/action-gh-release/releases)
- [Changelog](https://github.com/softprops/action-gh-release/blob/master/CHANGELOG.md)
- [Commits](718ea10b13...3d0d9888cb)

Updates `ossf/scorecard-action` from 2.4.3 to 2.4.4
- [Release notes](https://github.com/ossf/scorecard-action/releases)
- [Changelog](https://github.com/ossf/scorecard-action/blob/main/RELEASE.md)
- [Commits](4eaacf0543...2d1146689b)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: 7.0.1
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
- dependency-name: actions/setup-python
  dependency-version: 7.0.0
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: actions
- dependency-name: github/codeql-action/upload-sarif
  dependency-version: 4.37.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: actions
- dependency-name: aws-actions/configure-aws-credentials
  dependency-version: 6.2.3
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
- dependency-name: softprops/action-gh-release
  dependency-version: 3.0.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
- dependency-name: ossf/scorecard-action
  dependency-version: 2.4.4
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: actions
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-01 12:46:12 +01:00
dependabot[bot]
d81d7f82f1 build(deps): bump meson from 1.11.1 to 1.11.2 in /.github/workflows
Bumps [meson](https://github.com/mesonbuild/meson) from 1.11.1 to 1.11.2.
- [Release notes](https://github.com/mesonbuild/meson/releases)
- [Commits](https://github.com/mesonbuild/meson/compare/1.11.1...1.11.2)

---
updated-dependencies:
- dependency-name: meson
  dependency-version: 1.11.2
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-01 12:44:14 +01:00
Chris Down
248d6cf09d properties: Skip value building for nominal case
bus_message_print_all_properties() builds a PROP= string for every
property in the reply so that -p PROP=value filters can be matched
against it, but most queries never need this.

Take the normal `systemctl show` or `systemctl show UNIT` case. In that
case there is no filter. Even with `-p PROP` there is no value filter
since there is no value.

Avoid constructing the string entirely by comparing property names
directly against filter entries.

In my tests with a `systemctl show` over 160 units this brings the
instructions retired from 992.6M down to 960.5M, a reduction of 3.2%.

The same goes for property filters with units. When running:

    systemctl show -p UnitFileState -p ActiveState UNIT

...the instructions retired drops from 9.52M to 9.22M, a reduction of
3.2%. The output in each case is unchanged.
2026-08-01 00:53:16 -07:00
Chris Down
6a863b4dc3 properties: Peek the variant value type once (#43145)
bus_message_print_all_properties() peeks the variant type, but then the
print callback and the default bus_print_property() each peek the value
type again, so there can be up to two redundant calls per property. Peek
it once up front and pass it through.

With this, in my tests `systemctl show` over 160 units decreases in
instructions retired from 1167.6M to 1155.7M, so about 1%.
2026-07-31 18:16:56 -07:00
Chris Down
5293068fb3 properties: Peek the variant value type once
bus_message_print_all_properties() peeks the variant type, but then the
print callback and the default bus_print_property() each peek the value
type again, so there can be up to two redundant calls per property. Peek
it once up front and pass it through.

With this, in my tests `systemctl show` over 160 units decreases in
instructions retired from 1167.6M to 1155.7M, so about 1%.
2026-07-31 16:51:08 -07:00
Chris Down
5663ddaed7 properties: Skip found set building for nominal case
bus_message_print_all_properties() inserts every name it walks into the
found-properties set, but the set is only used to report missing requested
properties at debug level.

Request the set from systemctl only when properties were specified and debug
logging is enabled, avoiding the unnecessary work in normal operation.

In my tests with `systemctl show` over 160 units this brings the
instructions retired from 1167.8M down to 992.6M, a reduction of 15.0%.
The output is unchanged.
2026-07-31 16:41:53 -07:00
Christian Glombek
91d2131e20 test: TEST-89: remove temporary files when browse helpers return
The RETURN traps in the browse helpers only stopped the transient
varlinkctl unit; the mktemp'd output/error/scratch files were never
removed and leaked on every invocation. Remove them from the same trap,
after the unit has been stopped so that nothing is still writing to
them, and make that stop best-effort like in
testcase_browse_ifindex_zero_no_flap: if varlinkctl exited on its own,
the transient unit is already gone, and a failing stop would otherwise
abort the testcase under errexit and skip the removal.

testcase_browse_ifindex_zero_no_flap cleans up its output file from the
trap it already arms for the dummy link, which is an EXIT trap since
run_testcases runs each testcase in its own subshell.

While at it, tidy up the helpers' variable scoping: error_file was
accidentally a global, and i/svc were declared in the wrong functions
(they are used by check_both/check_first, via dynamic scoping).
2026-08-01 03:54:58 +09:00
Yu Watanabe
dda5008019 tmpfiles: fix log message about BSD lock 2026-08-01 03:17:00 +09:00
Yu Watanabe
994289a030 test: stage volatile deb packages for upgrade test, and retry failed units (#43209) 2026-08-01 01:48:48 +09:00
Yu Watanabe
d2685c303b tmpfiles: reject extra argument fields and make 'r'/'R' support age field (#43195)
This updates systemd-tmpfiles in two small areas:

- Reject non-empty argument fields for tmpfiles.d line types that do not
consume the argument field, instead of warning and silently ignoring
them.
- Let `r` and `R` tmpfiles.d entries honor the `Age` field when
`systemd-tmpfiles --clean` is used. The existing `--remove` behavior
remains unconditional.

The completed TODO entries are removed, and NEWS/man page documentation
is updated for the visible behavior changes.
2026-08-01 01:34:08 +09:00
Adam Dinwoodie
7b761dba0f core/timer: fix next trigger with RandomizedOffsetSec + Persistent (#42826)
When a calendar timer with RandomizedOffsetSec and Persistent=true fires a
catch-up activation, last_trigger is set to the current wall-clock time.
This inherently already includes any randomized offset, because the
trigger was that the activation time including the offset had passed.

When computing the next elapse, calendar_spec_next_usec() finds the next
calendar boundary after the base time, and then random_offset is added to the
result. If the base time already includes the offset, the next calendar
boundary is one period too far in the future, causing a scheduled activation
to be skipped.

Fix this by always subtracting random_offset from the base time before passing
it to calendar_spec_next_usec(), matching what the fallback branches (using
inactive_exit_timestamp or current time) already do. This puts the base into
"pre-offset calendar space" so that the next calendar match and subsequent
offset addition yield the correct next activation time.

Fixes #42337.
2026-08-01 00:53:33 +09:00
Armaan Sandhu
2bb179632f string-util: don't miss ANSI sequence at the very end in previous_ansi_sequence()
The backwards scan started at offset length-3, so the last position at which a
sequence can begin, length-2, was never examined. CSI sequences are at least
three bytes long and were thus unaffected, but two byte Fe sequences (ESC
followed by 0x40…0x5F) terminating the examined slice were missed.

ellipsize_mem() calls this to figure out whether a sequence ends exactly at the
current position, so that it can be skipped over, which is precisely the case
that was broken: such a sequence was instead counted as two visible cells and
copied through as text, and the string was ellipsized more aggressively than
requested. For example ellipsize("🐱🐱\x1bM🐱🐱\x1bM", 5, 0) returned a three
cell wide string rather than the five cells asked for.
2026-08-01 00:12:40 +09:00
Sinity
3e04f8f450 core/dbus: do not flush a user manager's bus that is not RUNNING
destroy_bus() flushes unwritten data for unprivileged managers so that
queued messages are not lost when a connection is torn down. However,
sd_bus_flush() first drives the connection to completion via
bus_ensure_running(): for a connection still in OPENING or
AUTHENTICATING this blocks the manager synchronously - a single-fd
ppoll, the event loop is not running - until the peer answers or
BUS_AUTH_TIMEOUT (= DEFAULT_TIMEOUT_USEC, 90 s by default) expires; a
connection in HELLO blocks the same way on the Hello call's own
method timeout. destroy_bus() is reached from four places: the
disconnect handler, manager_recheck_dbus(), the failed-setup path in
api_bus_instance_id_reply(), and bus_done() during normal shutdown or
reexec (via manager_free()).

Such a peer legitimately never answers: during session teardown,
dbus.socket can be (or re-enter) listening while the D-Bus service
behind it is hung or already gone, so connect() succeeds against the
socket backlog and the authentication request is never read. The user
manager then freezes mid-shutdown - or mid-reexec - for 90 s, with
every remaining unit stop (or the reexec itself) gated behind it.

This is the block traced in #16471 (2020, v245): the reporter's
strace shows the manager hanging in a single-fd ppoll with an ~89 s
timeout right after SIGTERM - bus_ensure_running() driving an
AUTHENTICATING reconnection - and their summary attributes it to the
flush. Their tested sd-bus-level patch (breaking the wait via a
SIGTERM-set flag) was met with "a work-around once things are already
bad, but we shouldn't even get in that state"; the same reply stated
the expectation this commit implements - the manager "should normally
protect itself ... and not issue dbus messages when the dbus service
isn't fully up". bus_foreach_bus() already applies that principle in
the other direction, skipping enqueue for connections that "haven't
started yet" via the same sd_bus_is_ready() check. 1166f4472d
("core/dbus: do not block the manager on GetId during bus
(re-)connection") removed the connect-time instance of the same class
of block, in code added in 2025. The flush here is twelve years
older: it dates back to the libsystemd-bus conversion (718db96199,
2013).

Only flush when the connection is currently RUNNING. This does not
change what gets delivered in the failure case this fixes: whatever a
non-RUNNING connection's write queue holds (auth/Hello traffic, and
any subscriber signal a per-unit or per-job bus_track attached without
a readiness check) was never actually sent by the old code either -
sd_bus_flush() calls bus_ensure_running() before it ever looks at the
write queue, so a connection that times out without reaching RUNNING
had its queued data silently discarded on close exactly as before,
just after blocking for up to 90 s first rather than immediately. The
one narrowing is a connection that would have completed authentication
within the timeout window: previously such traffic could still reach
the peer after the block; now it will not. Every destroy_bus() call
site is reached only once the manager has already decided the
connection is being torn down (disconnected, recognized as down, or
the process itself exiting/reexecuting), so this narrowing does not
trade a working delivery for a broken one.

Fixes #16471
2026-07-31 23:57:09 +09:00
Simon de Vlieger
d652f6dc44 selinux: wire up LabelContext in tmpfiles, firstboot, sysusers
These three one-shot tools operate on alternate roots via --root/--image
but until now created files with host SELinux labels, producing images
that fail to boot or run with enforcing mode because every file carries
the wrong security context.

Create a LabelContext from arg_root at startup and thread it through all
labeling call sites so the target image gets labeled according to its own
policy.

Signed-off-by: Simon de Vlieger <cmdr@supakeen.com>
2026-07-31 10:06:14 +02:00
Simon de Vlieger
f4f6a56db4 selinux: use LabelContext in label callbacks
With the plumbing and context type in place, make the SELinux pre/post
callbacks use the alternate context when label_context is non-NULL, so
files get labeled according to the target image's policy rather than the
host's.

Errors from the host kernel not recognising image-specific contexts
(EINVAL from setfscreatecon_raw) are logged at debug level and skipped
gracefully, since this is expected when the image carries labels the host
policy doesn't define.

Signed-off-by: Simon de Vlieger <cmdr@supakeen.com>
2026-07-31 10:06:13 +02:00
Simon de Vlieger
f2b82e5c20 selinux: add LabelContext for alternate-root labeling
When operating on an alternate root (--root/--image), SELinux labels must
come from that root's policy, not the host's. This requires opening a
separate selabel_handle against the target's policy database and
remembering the root path for prefix stripping.

Introduce LabelContext to carry both, and mac_label_context_new() to
set it up: it reads the target's SELinux config, validates SELINUXTYPE to
prevent path traversal, sets the policy root, and opens a label database
scoped to the target image.

Signed-off-by: Simon de Vlieger <cmdr@supakeen.com>
2026-07-31 09:49:41 +02:00
Simon de Vlieger
6b0e3ea222 label: plumb label_context through LabelOps
SELinux labeling with --root/--image needs per-call context to carry an
alternate policy database and root prefix. The current LabelOps interface
has no way to pass this, forcing any solution to rely on global state.

Add a LabelContext *label_context to the label_ops callbacks and all
intermediate layers. Generic filesystem functions that most callers use
(xopenat_full, write_string_file_full, etc.) get a _label variant
carrying the extra parameter, with inline wrappers preserving the
original signatures so the vast majority of call sites remain untouched.

Signed-off-by: Simon de Vlieger <cmdr@supakeen.com>
2026-07-31 09:49:41 +02:00
Yu Watanabe
63e35ca3f9 selinux: relax error handling in permissive mode (#36929)
Error returned from security_compute_create_raw() means that kernel
couldn't compute target context. Very likely because file context is not
known to the policy, i.e. security.selinux xattr contains some garbage
value and we are running in permissive mode, otherwise returned context
would be "unlabeled_t" instead of getting an error.

mac_selinux_get_create_label_from_exe() is used to figure out create
label for socket units and we fail to start the socket if we can't
figure out that label.

However, it may be necessary to start some sockets in order to get to
the point when we launch the service that relabels (in permissive mode)
the entire filesystem and reboots.
2026-07-31 12:49:14 +09:00
Yu Watanabe
3abe380d04 core/service: append the original error cause in the debugging logs 2026-07-31 11:30:32 +09:00
Michal Sekletar
a3fee62707 core/service: ignore SELinux label errors in permissive mode
Return -ENODATA instead of the raw error when SELinux is permissive, so
the caller falls back to the default label. This is needed to allow
relabeling service to start on systems where file contexts maybe
invalid.
2026-07-31 11:30:32 +09:00
Luca Boccassi
fb3581af65 test: find out tpm device rather than hardcoding it in TEST-92-TPM2-SWTPM
Looks like the device might change depending on the boot sequence, so
discover it in the test rather than hardcoding it to /dev/tpmrm0.

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

Follow-up for 1b1900a6f3
2026-07-31 11:06:30 +09:00
Yu Watanabe
71a2af43f9 core: quote each exec directory entry when serializing
Quote each serialized exec directory entry, and use extract flags
compatible with config_parse_exec_directories() when deserializing.
This allows paths containing spaces and escaped characters to round-trip
correctly.

Fixes #41853.
Replaces #42686.
2026-07-31 10:46:50 +09:00
Frantisek Sumsal
6d7a2ec6ba ci: fix /etc and /usr ownership
Recent Ubuntu 24.04 GHA images have /etc and /usr owned by runner
instead of root, which breaks some of our tests. This has been filed to
GH as https://github.com/actions/runner-images/issues/14477, so let's
work around this in our jobs until it's fixed.
2026-07-30 15:25:30 +01:00
Luca Boccassi
cdc3fd019b test: retry units failed during package replacement in TEST-88-UPGRADE
Retry units that still exist and clear stale state for units removed by
a downgrade, as packages might be old and not have new units that were
added in the latest version.
2026-07-30 09:13:35 +01:00
Luca Boccassi
f029c336e9 mkosi: stage volatile deb packages for upgrade test
Prepare scripts run before volatile packages are installed, so parse
the list from the config to ensure they are all included to avoid
failures due to some packages missing from the list.

Follow-up for 28e1f84d6a
2026-07-30 09:13:35 +01:00
dongshengyuan
249421e75e tmpfiles: honor age for r/R cleanup
Let r and R lines participate in --clean when they specify an age. The
target itself is removed only after its selected file or directory
timestamps have aged enough; --remove remains unconditional.

Follow-up for: beca6b6e6b
2026-07-30 13:45:52 +08:00
Baurzhan Muftakhidinov
c00fea9db1 po: Translated using Weblate (Kazakh)
Currently translated at 100.0% (286 of 286 strings)

Co-authored-by: Baurzhan Muftakhidinov <baurthefirst@gmail.com>
Translate-URL: https://translate.fedoraproject.org/projects/systemd/main/kk/
Translation: systemd/main
2026-07-30 13:55:48 +09:00
Daniel28972897
b2cd050073 libudev: cache the errno for a failed parent lookup
udev_device_get_parent() caches the result of device_new_from_parent()
in udev_device->parent on first call. device_new_from_parent() sets
errno correctly via return_with_errno() when it fails, so a caller
gets the right errno on the first invocation. But on any subsequent
call for the same object, the cached NULL is returned directly without
recomputing anything, so errno reflects whatever happened in between
rather than the original failure reason.

Cache the errno alongside the parent pointer (new parent_errno field,
zero-initialized like the rest of the struct via udev_device_new()'s
compound literal) and restore it whenever the cached parent is NULL.
2026-07-30 07:24:17 +09:00
Frantisek Sumsal
9d4019b9b7 ci: build the release clang build with _FORTIFY_SOURCE=3
Since this combination is known to cause interesting issues in our
allocation machinery.
2026-07-30 01:18:58 +09:00
Frantisek Sumsal
a56d7db48f alloc-util: make malloc_sizeof_safe() compatible with clang's _FORTIFY_SOURCE=3
Turns out that clang's interprocedural analysis is quite smart and can
look through our expand_to_usable() trick, which then causes crashes
with _FORTIFY_SOURCE=3.

clang's interprocedural analysis can see that expand_to_usable() simply
returns its first argument, so it replaces all uses of the return value
with that argument (the original realloc() result). This effectively
bypasses expand_to_usable()'s alloc_size attribute, causing the fortify
check to use the (smaller) size from realloc() instead, which eventually
leads to a false-positive buffer overflow:

$ build/test-varlink-idl
/* test_parse_format */
...
*** buffer overflow detected ***: terminated
Aborted                    (core dumped) build/test-varlink-idl

This is not an issue with gcc (at least not yet), since gcc sees
expand_to_usable() as an opaque user-defined allocation-like function
and simply trusts the alloc_size attribute that comes with it.

To fix this, let's add a simple no-op barrier to malloc_sizeof_safe()
that clobbers the input pointer, which causes
__builtin_dynamic_object_size() to return (size_t)-1 - this is
interpreted as an "unknown" size by the following fortify check which is
then skipped instead of triggering the assertion.

Similarly, test-alloc-util now doesn't call malloc_usable_size()
directly but instead goes through malloc_sizeof_safe(), so it's also
guarded by the barrier.

This follows the already established pile of similar workaround for the
same class of issues we encountered with gcc, namely [0], which prompted
[1], that was later reverted in [2], and then followed by another couple
of fixes in [3] and [4].

Resolves: #43178

[0] https://github.com/systemd/systemd/issues/22801
[1] 0bd292567a
[2] 2cfb790391
[3] 7929e180aa
[4] 4f79f545b3
2026-07-30 01:18:58 +09:00
Eric Curtin
21ab2fe6ec shared/switch-root: sync only file systems becoming unreachable, not everything
switch_root() calls a blanket sync() before detaching the old root
file system, in order to make sure it is in a good state before it
becomes unreachable via MNT_DETACH/pivot_root().

A global sync() however flushes out *every* mounted file system on
the system, not just the ones we are actually about to detach. On
real-world systems that commonly have several additional mounted file
systems (separate /home, /var, additional data partitions, network
shares, removable media, ...) this needlessly delays switch_root() with
completely unrelated I/O. This matters in particular for
initrd-switch-root.service, which runs this code on the critical path
of pretty much every single boot with an initrd, and for soft-reboot.

Replace the global sync() with a new sync_departing_file_systems()
helper that walks /proc/self/mountinfo and calls syncfs() on every
file system except:

  - 'new_root' and anything mounted below it: these remain mounted
    and reachable after the transition and keep being synced normally
    as part of their regular life cycle, so they don't need to be
    force-flushed here.

  - API/pseudo file systems (proc, sysfs, cgroupfs, autofs, ...),
    network file systems, and overlayfs (which has no backing store
    of its own), as determined by the new fstype_is_worth_syncing()
    predicate. There is nothing meaningful to flush on any of these,
    and more importantly, opening an untriggered autofs mount point
    would needlessly trigger it, and opening a stale network mount
    could block for a long time - exactly what we are trying to avoid
    on this code path.

  - Any flavour of FUSE (plain 'fuse', 'fuseblk', or a
    'fuse.<subtype>', e.g. sshfs, rclone, gvfs, ntfs-3g, exfat-fuse,
    ...), classified via the new fstype_is_fuse() predicate in
    src/basic/mountpoint-util.c, plus a few other, non-FUSE guest/host
    file sharing file systems with the same "backed by a companion
    daemon/hypervisor that could be wedged" risk profile (virtiofs,
    vboxsf, vmhgfs). All I/O against any of these, including the
    syncfs() we'd otherwise issue, is routed through an arbitrary
    userspace daemon (or, for virtiofs/vboxsf/vmhgfs, the host/
    hypervisor side), which could hang indefinitely if wedged, dead,
    or otherwise unresponsive - there's no timeout on this code path.
    'fuseblk' might sound exempt given the name, and does wrap an
    actual block device, but that doesn't bound its syncfs() latency
    by the kernel block layer alone the way a native block device
    file system's is: the request is still serviced by the same FUSE
    daemon as any other FUSE variant, and can hang exactly the same
    way, so it is excluded here too, trading its comparatively minor
    data-safety benefit for avoiding that unbounded hang risk.

    '9p' (which can be used with a writeback cache and hence carry
    real dirty data, e.g. common in QEMU/KVM guests) and the
    shared-storage cluster file systems 'gfs', 'gfs2' and 'ocfs2'
    (which fstype_is_network() also happens to classify as "network"
    file systems, since they additionally rely on a networked
    distributed lock manager for coordination) are deliberately *not*
    excluded: unlike FUSE/virtiofs/etc., these are serviced by a
    mature, in-kernel client (talking directly to the hypervisor over
    a bounded virtio transport, or to real - if shared - block
    storage), not an arbitrary, potentially wedged userspace daemon,
    so they carry the same bounded, local sync latency any other
    block device backed file system already does here. Skipping them
    would needlessly sacrifice the data-safety guarantee the original
    blanket sync() gave them, without meaningfully improving safety.

  - Mount table entries that we can positively confirm are currently
    shadowed by another mount stacked on top of them at the same
    path: since we can only reach a file system by (re-)opening its
    target path, and that always resolves to whatever is currently on
    top, syncing by path alone could end up flushing the wrong
    superblock. Detect this via the new shared
    libmount_fs_id_matches_path() helper (factored out of, and now
    also used by, the pre-existing get_sub_mounts(), which needed the
    exact same check for the same reason). This same check is also
    applied to a mountinfo entry whose target is 'new_root' itself
    (not just anything strictly below it): comparing its mount ID
    against new_root's own, freshly determined mount ID tells apart
    the file system that is actually still reachable there (which we
    continue to skip) from a stale entry that merely shares the exact
    same path (e.g. if new_root wasn't already its own mount point
    and got bind-mounted onto itself earlier in switch_root()), which
    is departing just the same and must not be skipped just because
    of that coincidence.

Every failure mode that means we can no longer be sure we've covered
every departing file system correctly - libmount being unavailable,
/proc/self/mountinfo (or a specific entry in it) failing to parse,
being unable to tell whether a specific entry is currently shadowed,
or syncfs_path() itself failing for an otherwise-eligible entry - is
handled the exact same way: propagate the error up and let the sole
caller, switch_root(), fall back to one plain, global sync() to cover
everything, rather than deciding on and performing that fallback (or,
worse, silently skipping the affected file system without any
fallback at all) at each of these different spots individually. This
should be rare in practice, so it doesn't meaningfully undercut the
benefit of the targeted sync in the common case.

Everything else that's actually about to become unreachable (the old
root itself, but also any other, unrelated real file system that
happens to be mounted underneath it and gets detached along with it)
is still synced, so this keeps the same safety guarantee the original
blanket sync() gave for file systems that actually do go away here.
Uses the existing syncfs_path() helper for the actual open+syncfs.

sync_departing_file_systems() itself returns -EOPNOTSUPP if libmount
support isn't compiled in, handled the same way by switch_root() as
any of its other error returns.

Note we intentionally don't use O_PATH file descriptors here: syncfs()
requires a 'real' file descriptor and fails with EBADF on O_PATH ones.

Also note there remains an inherent, narrow TOCTOU race between the
mount-ID check described above and the open() syncfs_path() performs
right after it: if something else mounts something new on top of a
given 'path' in between, that open() could still end up triggering an
automount, or hanging on a stale mount, since there is no open()/
openat() equivalent of statx()'s AT_NO_AUTOMOUNT to prevent this for a
"real" (non-O_PATH) file descriptor. Unlike the other failure modes
handled here, a hanging open() can't be recovered from by falling back
to sync() afterwards, since control never returns to do so. Closing
this fully would require disproportionate effort (e.g. performing the
open() in a separate, killable/timeout-bounded process) for a window
that is already narrow, since this code only runs with most other
activity on the system already quiesced during the switch_root()
transition itself, so it is accepted as-is (see the comment at the
call site for details).

This mirrors the same reasoning already applied to the shutdown path
in src/shutdown/shutdown.c, which deliberately avoids a 'dumb' sync()
there for identical reasons.
2026-07-30 01:15:03 +09:00
Yu Watanabe
08ca33fdde core: postpone dbus queue dispatch while API bus setup is pending (#43200)
Since 1166f4472d the API bus setup
and the subscriber coldplug happen only once the asynchronous GetId
reply is processed by the event loop. After a daemon-reexec,
manager_dispatch_dbus_queue() runs before subscribers were registered
and consumed send_reloading_done, so the one-shot Reloading(false)
signal was never sent.

Clients that wait for this signal to detect that a reexec finished time out.

Track the pending setup and hold the flag until the reply handler has
re-added the subscriptions.

Also affects v261.2 via backport 26f3717e27.
2026-07-29 20:38:21 +09:00
r-vdp
2e254eba03 test: add case for the Reloading bus signal
Check that the manager broadcasts Reloading(true/false) on the API bus
for daemon-reload, and the one-shot Reloading(false) after a
daemon-reexec, which requires the subscribers of the previous instance
to be coldplugged before the D-Bus queue is dispatched.
2026-07-29 11:17:14 +02:00
r-vdp
266b3e5021 core: postpone D-Bus queue dispatch until the API bus is set up
Since 1166f4472d ("core/dbus: do not block the manager on GetId during
bus (re-)connection") the API bus setup and the subscriber coldplug
happen only once the asynchronous GetId reply is processed by the
event loop. After a daemon-reexec, manager_dispatch_dbus_queue() runs
before subscribers were re-added, so bus_foreach_bus() skipped the
API bus and queued messages were lost for subscribers. In particular
the one-shot Reloading(false) signal was never sent, and clients that
wait for it to detect that a reexec finished timed out.

Track whether bus_setup_api() has run for the current API bus
connection, and postpone dispatching the queue until then.
2026-07-29 09:52:57 +02:00
dongshengyuan
e347f63b0f tmpfiles: reject unused argument fields
Line types which do not use the argument field used to warn and ignore
a non-empty field. Treat that as invalid configuration instead, so typos
are not silently accepted.

Follow-up for: 614cc34f3a
2026-07-29 15:29:54 +08:00
Paul Meyer
57f8a85a21 cryptsetup: measure volume key and keyslot via the pcrextend Varlink service (#43109)
Motivated by
https://github.com/systemd/systemd/pull/43041#discussion_r3595022610.

Switch systemd-cryptsetup's volume-key and keyslot measurements from
driving the TPM directly (tpm2-util) to the io.systemd.PCRExtend Varlink
service, aligning it with how the verity and imds measurements already
work.

Some notes on decisions taken:
- The volume key is sent over the wire. systemd-pcrextend will do the
hmac. The socket is root only. Otherwise we would need to do bank
negotiation via varlink and pollute the interface with it.
- `tpm2-measure-bank=` deprecated/dropped. Same reason as above.
- `tpm2-device=` now only affects unlocking. The device for measurements
is selected by pcrextend.
- Measuring requires the presence of `systemd-pcrextend.socket` in the
initrd, should be already given as systemd-veritysetup relies on it,
too.
- Logs are done on the pcrextend side.
2026-07-29 07:21:08 +02:00
Eric Curtin
d47b07d05f test-bpf-restrict-fs: skip if manager startup fails due to lack of privileges (#43202)
test-bpf-restrict-fs.c creates a Manager with RUNTIME_SCOPE_SYSTEM, which
tries to set up the real system runtime directory hierarchy (e.g. create
/run/systemd/), and that requires privileges the test process may not
have (e.g. unprivileged sandboxed builders such as OBS).

Previously this was masked because bpf_restrict_fs_supported() did a
trial open/load/attach of the BPF program itself, which also requires
elevated privileges and so failed first, causing the test to skip
before ever reaching manager_new()/manager_startup(). Since
bpf_restrict_fs_supported() no longer does that trial load, the test
now reaches manager_new()/manager_startup() in these unprivileged
environments and hard-fails instead of skipping, e.g.:

  Assertion failed: Expected "manager_startup(m, NULL, NULL, NULL, NULL)"
  to succeed, but got error: -13/EACCES

Use the same manager_errno_skip_test() pattern already used by other
tests (test-engine.c, test-execute.c, test-path.c, ...) to skip
gracefully when manager_new() or manager_startup() fail due to missing
privileges, instead of asserting.

Follow-up for c99678eeda.
2026-07-29 11:46:05 +09:00