Commit Graph
7879 Commits
Author SHA1 Message Date
Chris Down 00cf56abbd core: Add SERVICE_RUNNING_REVALIDATING state
For a Type=dbus service we sometimes want to keep treating it as running
while its bus name has briefly gone away (for example, due to a broker
restart).

SERVICE_RUNNING_REVALIDATING is active and keeps its main process like
SERVICE_RUNNING, but it's deliberately not part of the runtime timer
set, so RuntimeMaxSec= is paused while we sit in it.
2026-09-01 02:12:52 +09:00
Yu Watanabe dee2ea17c7 Update Linux kernel headers from v7.3-rc1 (#43573) 2026-09-01 00:59:36 +09:00
Christian Brauner 1783f8c3de keyring-util: pass the buffer size to KEYCTL_DESCRIBE
While keyring_describe() allocates a 64 byte buffer it still passes the
value of c as the buffer length. It's -1 on the first iteration. So
keyctl_describe_key() copies the whole description whenever buflen >=
its length. So any key whose description exceeding 64 bytes overflows.
Pass the actual buffer size.

Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>

[zjs: adjust comment]
2026-08-31 17:24:29 +02:00
Yu Watanabe 69c8578c17 test: use linux/magic.h from our tree
We copy linux/magic.h from the kernel source tree and use it when
building systemd. Let's also make the kernel-filesystem-magics test
use the copy in our tree rather than the one installed on the system.

To achieve that now the 'check' command takes both 'cpp' and
'system_include_args' from meson.
2026-08-31 21:17:30 +09:00
Yu Watanabe 8220fcf4fe filesystem: correctly recognize failfs
The kernel v7.3-rc1 introduces failfs:
https://github.com/torvalds/linux/commit/fa0d6d945e5ce96cff14b114eec7527f13d7f23a
2026-08-31 19:43:10 +09:00
Yu Watanabe 69a54c37ac options: introduce OPTION_COMMON_VERSION_WITH_V and version_only()
The man page udevadm(8) have explicitly documented that the option -V is
a short form of --version. Let's not hide the short form in the help
message.

This introduces OPTION_COMMON_VERSION_WITH_V then use it in udevadm,
udevd, and run0.

Alos, this moves print_version() to build.c, and renames it to
version_only(). Now the function is also used in udevd amd test-libudev.

With this change, the -V option is hidden only in dmi_memory_id and
scsi_id. So, this removes the OPTION_COMMON_VERSION_WITH_HIDDEN_V macro
and explicitly list the hidden option in their code.
2026-08-29 07:40:35 +09:00
Zbigniew Jędrzejewski-Szmek 05fb4c6e27 Ignore $SYSTEMD_INVOKED_AS if empty
Let's treat unset SYSTEMD_INVOKED_AS and SYSTEMD_INVOKED_AS='' the same.
I encountered this when testing various --help outputs. It is often
more convenient to override a variable with VAR= instead of removing it,
in particular on the commandline. But we'd then print help with the
program name missing. We look at the variable in two places, so adjust
both as in $subject.
2026-08-28 14:50:10 +02:00
Yu Watanabe 445c6ce8a2 compress: several fixlets for decompressor (#43506) 2026-08-27 07:58:38 +09:00
Yu Watanabe d81e6b93d6 process-util: split out procfs_get_stat_flags() from pid_is_kernel_thread() 2026-08-27 05:50:14 +09:00
Yu Watanabe dac2b39405 compress: strictly check if stream finished on decompress
Previously, even when the compressed data was truncated, or had
trailing garbage, the decompressor might not detect it.

To fix the issue, update the check if stream is finished.
With this change, now decompressor_push() must be called with
size == 0 to finalize the stream.
2026-08-27 04:36:57 +09:00
Yu Watanabe d9b6e8663c compress: check cursor position in should_sparse()
Otherwise, the result will be broken, as skipped area by lseek() is not
cleared.
2026-08-27 04:36:57 +09:00
Yu Watanabe f577c38a52 compress: inline error handling 2026-08-27 04:36:50 +09:00
Yu Watanabe fefe8f3132 compress: use consistent error code for failure in BZ2_bzDecompressInit() 2026-08-27 04:36:29 +09:00
Yu Watanabe b9dbbccd20 compress: fix indentation and add short comment 2026-08-27 04:35:03 +09:00
Yu Watanabe d365c4cd52 compress: fix error handling for lzma_lzma_preset()
Follow-up for 91d6f1ee53.
2026-08-27 04:34:34 +09:00
Yu Watanabe 6fe09adf81 network: several follow-ups for proxy neighbor setting (#43408)
Follow-ups for 08bebda611.
2026-08-27 00:09:59 +09:00
Zbigniew Jędrzejewski-Szmek 34d4d50d08 Another batch of conversions to COMMAND and additions of --introspect-cli (#43512) 2026-08-26 15:22:50 +02:00
Zbigniew Jędrzejewski-Szmek 4f2b0e977c core: convert to VERB_COMMAND and add --introspect-cli
--introspect-cli follows the same deferred pattern as --help: parse_argv()
only records the action, and it is executed in the same place where
ACTION_HELP and ACTION_VERSION are handled.

The help is looked up by explicit name: in the multicall configuration
the systemd and systemd-executor commands share one binary, so the
"first COMMAND" default would depend on link order.

The "This program takes no positional arguments." line is dropped from
the help output — the default "[OPTION…]" synopsis already says so.
(And also, this is not quite true. It does take positional args when
called as init.)
2026-08-26 12:22:15 +02:00
Zbigniew Jędrzejewski-Szmek ed595e6b67 basic/argv-util: drop unused code 2026-08-26 12:15:16 +02:00
Zbigniew Jędrzejewski-Szmek dc39dc759b Pressure metrics (#43377)
This adds a slightly extended and improved version of the patch we had
internally.
2026-08-25 14:45:16 +02:00
Zbigniew Jędrzejewski-Szmek 27f63ef988 basic/procfs-util: make procfs_cpu_get_ticks lenient again
In review it was raised that the file is often synthesized and that this
synthetization might not include all the fields, let's allow the more
recently added fields to be missing to avoid a regression in
compatibility.
2026-08-24 23:56:06 +02:00
Zbigniew Jędrzejewski-Szmek b8cc2ef04b report-basic: cpu, memory, pressure, and disk metrics
Extend the io.systemd.Basic metric families with host-level runtime
metrics: cumulative per-state CPU seconds, memory in use (MemTotal minus
MemAvailable), swap in use, the kernel's 10s pressure stall averages
(cpu/memory/io x some/full). Partitions and stacked devices are excluded
from the disk counters, since their traffic is already accounted for in
the parent device.

Also extend the TEST-74 report subtest with checks for the new metrics.

Network metrics are not added, because the service runs with
PrivateNetwork=yes, and it doesn't make sense to report stats for 'lo'.

After some back-and-forth, I settled on "CPUUsage". We use this scheme of
capitalization in other metric family names: "IPv4Public", "IPv6Public",
IPv4AddressState", "IPv6AddressState", "OSRelease" "SMBIOS" "BootID",
"CPUsOnline", "MachineID", "MachineInfo", "OSRelease",
"SMBIOS.SystemManufacturer", "TPM2.Manufacturer", "TPM2.VendorString",
"IOReadBytes", "IOReadOperations", "CGroup". The exception is
"io.systemd.cgroup.CpuUsage". I think we should treat that one as a
mistake and consider changing it to conform.
2026-08-24 23:56:06 +02:00
Yu Watanabe 98b867040e compress: several trivial cleanups (#43490) 2026-08-24 21:12:06 +09:00
Lennart Poettering 9139f3c53f switch-root: do not check fs to sync against allowlist
This drops a good chunk of 21ab2fe6ec
again, which I think is plainly wrong or at the very least too
overengineered.

1. it's wrong to assume that overlayfs layers are mounted elsewhere in
   the fs. it's quite likely they aren't. and overlayfs correctly passes
   through fsync() to the top layer, hence we really should keep syncing
   it.

2. network file systems deserve syncing. This code here runs in the
   initrd, where a very restrictive set of file systems is mounted and
   which runs for a very short time only, i.e. the circumstances haven't
   really changed. Hence I am very sure it's better to sync file systems
   here than not to, we do this for safety reasons after all.
   Reliability always trumps speed here, we should not give up
   correctness over presumed speed improvements.

3. There's zero reason to believe FUSE doesn't need syncing. We live in
   a world where increasingly complex kernel file systems are moved to
   userspace, and hence FUSE can be used to implement *anything*. Hence
   we should sync it. Yes, FUSE means some backing process needs to run,
   but that's a job for the initrd to get right: make sure the process
   runs properly over the switch root if the mount is left in tact over
   the switch root too.

Hence, dumb this all down and drop the weird fine tuning here.
2026-08-24 14:06:59 +02:00
Yu Watanabe 20923e8ddc compress: use dlopen_compress() at one more place 2026-08-24 03:30:52 +09:00
Yu Watanabe 7ea7833b86 compress: shorten code a bit 2026-08-24 03:30:52 +09:00
Yu Watanabe 1e7a69ff87 compress: use decompressor_new() at several more places 2026-08-24 03:30:52 +09:00
Yu Watanabe 87693c7073 compress: make decompressor_new() accept NONE 2026-08-24 03:30:52 +09:00
Yu Watanabe 4e2cb2bdf1 compress: use dlopen_compress() in decompress_stream() 2026-08-24 03:30:52 +09:00
Yu Watanabe 8f0bc58664 compress: introduce dlopen_compress() and friends 2026-08-24 03:30:52 +09:00
Zbigniew Jędrzejewski-Szmek ff54321e3c basic/procfs-util: stop counting guest time twice
The kernel reports guest usage in guest/guest-nice and also includes it in
user/nice. By adding the guest and guest-nice values, we were counting
those ticks twice.

C.f. https://gitlab.com/procps-ng/procps/-/blob/master/library/stat.c?ref_type=heads#L612-615
> note: we exclude guest tics from xtot since ...
>            'user' already includes 'guest'
>            'nice' already includes 'gnice'
> (see linux sources: ./kernel/sched/cputime.c, kcpustat_cpu_fetch)

Rewrite procfs_cpu_get_usage() to use procfs_cpu_get_ticks() and fix the
accounting error.
2026-08-21 09:17:51 +02:00
Zbigniew Jędrzejewski-Szmek efa45f5f47 basic/procfs-util: add procfs_cpu_get_ticks() 2026-08-21 09:17:51 +02:00
Zbigniew Jędrzejewski-Szmek 9b6911d2e6 basic/psi-util: add lookup table for PressureType 2026-08-21 09:17:51 +02:00
Yu Watanabe f3ada8a0fb network: introduce and use sysctl_write_ip_property_tristate() helper function
This also break some long lines.
2026-08-17 17:18:57 +09:00
Yu Watanabe 7ae2bc9199 pidfd-util: introduce pidfd_info_mask_is_supported() helper function
Since kernel v6.19, ioctl(PIDFD_GET_INFO) can return the set of
supported flags when PIDFD_INFO_SUPPORTED_MASK is specified.

This allows checking whether, e.g., PIDFD_INFO_COREDUMP_SIGNAL is
supported by the running kernel.
2026-08-15 01:35:23 +09:00
Yu Watanabe f807a32125 coredump: do not leak TID in the host to container (#43349)
PID, UID, and GID are converted by sending struct ucred, however, TID
was not converted. Let's convert TID if corresponding pidfd exists, and
discards TID otherwise.

Fixes 4c7af7d9d1.
2026-08-15 01:38:04 +09:00
Yu Watanabe cad2c455ec fstab-filter: fix preserve fstab option escaping (#43274)
Fixes #42787.
2026-08-14 00:23:47 +09:00
wyu 7b00f957fe strv: drop the escape_separator flag from strv_join_full()
Now that fstab_filter_options() no longer uses strv_join_full() with
escape_separator=true (it splits with EXTRACT_UNESCAPE_RELAX and joins the kept
options verbatim), the escape_separator flag has no users. Drop it from
strv_join_full() and its wrapper strv_join(), and update the remaining callers in
kernel-install and the tests accordingly.
2026-08-13 11:17:23 +08:00
wyu 609f8d0214 extract-word: also handle EXTRACT_UNESCAPE_RELAX in the escape branch
extract_first_word() handled a backslash followed by another character in the
escape-processing branch only when EXTRACT_CUNESCAPE or EXTRACT_UNESCAPE_SEPARATORS
was set. With EXTRACT_UNESCAPE_RELAX alone, the backslash was silently dropped and
only the following character kept, which is inconsistent with the documented "keep
invalid escapes verbatim" intent of RELAX. Let RELAX also enter that branch, so an
invalid escape like "\x" is preserved verbatim as "\x" rather than collapsing to
"x".

EXTRACT_UNESCAPE_RELAX is not used on its own anywhere outside the test cases —
the non-test callers always combine it with EXTRACT_CUNESCAPE, which already enters
this branch — so only the test cases that use RELAX by itself are affected, and
their expectations are updated accordingly.
2026-08-13 10:36:11 +08:00
Armaan Sandhu 32ac7af788 strv: treat newlines as hard line breaks in strv_rebreak_lines()
A newline embedded in an input entry only reset the width counter and the
leading-whitespace state, but the text collected before it was never flushed.
If nothing but whitespace followed the newline, the end-of-line path then saw
that we were still in the leading whitespace and emitted an empty line,
dropping everything before the newline: "foo\n" turned into "".

Newlines also didn't start a new output entry, so returned entries could
contain newlines and be wider than the requested width, even though callers
expect one output entry per output line.

Flush the collected line at the newline instead, reusing the same logic as at
the end of the string, and treat a trailing newline as terminating the last
line rather than adding an empty one.
2026-08-13 07:11:49 +09:00
zhaoshuang abffa868a8 virt: detect Alibaba Cloud ECS as KVM
Alibaba Cloud ECS instances expose "Alibaba Cloud ECS" in DMI
product_name/bios_vendor and "Alibaba Cloud" in sys_vendor. None of
these match dmi_vendor_table[], so systemd-detect-virt --vm reports
"none" on these machines, even though they run on a KVM-based
hypervisor. This is especially visible on ARM64 instances, where the
CPUID fallback does not exist (x86 only) and /proc/device-tree is
not populated.

Add "Alibaba Cloud ECS" to dmi_vendor_table[], mapping to
VIRTUALIZATION_KVM. The narrower prefix avoids matching the bare
"Alibaba Cloud" sys_vendor value, reducing the false-positive
surface for Alibaba's bare-metal (X-Dragon) instances compared to
the original broader prefix. bios_vendor also carries the same
string on ECS VMs though, so the protection is not complete —
fully resolving the VM-vs-bare-metal ambiguity would need the
SMBIOS BIOS-Characteristics bit check that the Amazon EC2 entry
uses.

The existing "back to DMI" fallback path in detect_vm() reports
"kvm" on both x86 and ARM64.
2026-08-12 04:12:19 +09:00
Yu Watanabe 918f1462d7 pidref: introduce pidref_set_pid_full() and friends
By passing the PIDFD_THREAD flag, we can get pidfd of a worker thread.
The flag is supported since kernel v6.9.
2026-08-11 00:27:15 +09:00
Yu Watanabe f8f2860750 core/service: Prevent accidental service termination during reload (#39692)
We currently blindly send the configured reload signal (e.g. SIGHUP or
SIGUSR1) to the main service PID for Type=notify-reload units, even if
the service hasn't installed a userspace handler. This can lead to
invoking unintended default behavior (typically process termination) in
daemons which later deprecate and remove their reload handler.

This is a real problem we have seen in production on multiple occasions.
In one particularly egregious instance, a production distributed storage
service had a large percentage of its nodes all terminate at once when
sent a reload signal. In this case a signal handler had been removed,
but another place still sending the signal was missed.

To mitigate this, introduce two new checks for Type=notify-reload
services:

1. On READY=1: When the service first sends READY=1 during initial
startup, we check for the handler. If it's missing, the service startup
is failed with SERVICE_FAILURE_PROTOCOL. This enforces the contract that
services *must* install their handler before signalling readiness.

2. On reload: Immediately before sending the reload signal, we check
again. If the handler is now missing, we log a warning but still send
the signal. This preserves the requested operator action while making
the missing handler visible.

The startup check catches definite static misconfiguration before the
service is accepted as ready. The reload check is advisory because the
service has already started successfully, but warns if its handler later
disappears. Together these provide a best-effort safety net while
preserving the agreed reload semantics.
2026-08-07 01:23:03 +09:00
Yu Watanabe 5f53643138 sysctl: add --verify option to verify written values (#43258) 2026-08-06 05:46:11 +09:00
Chris Down b64b996119 process-util: Add helpers to check for signal handler presence
Add new pidref_has_sigcgt() and pidref_has_sigblk() helpers. These read
the SigCgt and SigBlk bitmasks from /proc/<pid>/status to detect either
traditional signal handlers installed via sigaction(2), or blocked signals
that are typically handled via signalfd(2), such as through
sd_event_add_signal().

Both mechanisms represent valid ways to handle a signal without invoking
the default action. Share the parsing and pidref verification between the
two public helpers.
2026-08-04 16:51:37 -07:00
Yu Watanabe 2bb1f6a651 env-file: cleanups for write_env_file_label()
Explicitly call label_ops_post() where necessary with specific
arguments. Previously, regardless if fopen_tmpfile_linkable_at()
success, label_ops_post() was called but its argument was heavily
conditionalized. Let's call it both on failure and success cases
with specific arguments. This should be easy to read.

This also
- moves variable declarations where used,
- drops unnecessary boolean flag call_label_ops_post.

No functional change. Just reafactoring.

Hopefully silence CID#1664328, though it is false-positive.
2026-08-04 14:37:52 +09:00
Yu Watanabe 23fbf7cf1d sysctl-util: introduce sysctl_write_verify()
This is useful when writing coredump pattern. But the logic itself is
quite generic. Let's add the helper in our basic library.
Preparation for later change.
2026-08-03 14:25:49 +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
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
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