Commit Graph

90866 Commits

Author SHA1 Message Date
dongshengyuan
d73f3879f0 repart: drop legacy FactoryReset EFI variable
Follow-up for 9e050b0458.
2026-07-28 19:51:45 +09:00
Axel
9e60701fb1 Fix typo in 'website' in README.md 2026-07-28 19:46:34 +09:00
Chris Coulson
f0f3687700 tpm2: Improve how NvPCR protection works.
NV indexes created in the storage hierarchy can be undefined and
redefined with TPM owner auth. Because of this, NvPCRs need some way
to prevent them from being redfined in a way that allows spoof
measurements to be replayed.

The current approach requires knowledge of a secret ("anchor secret")
in order to derive the initial NvPCR measurement and to derive a
measurement to an existing PCR (9). The credential is protected by the
TPM with a PCR policy. Without access to the credential, it's not
possible to replay measurements to a newly defined NvPCR without
breaking the binding with the measurement in PCR 9. However, this
approach has a couple of issues:

- The credential is currently only protected by PCR11. As it's not
  protected by the rest of the boot chain, it's possible to boot other
  operating systems in order to replay the PCR11 measurements and
  recover the secret. Note that as the NvPCR anchoring happens in early
  boot, the credential is stored in the ESP.
- Someone with privileged access to a system can just create a new
  credential containing a known secret and store this in /var/lib and
  the ESP. The NvPCRs are anchored with this known secret on subsequent
  boots, and therefore the measurements can no longer be trusted.
  Imagine the scenario where privileged access is theoretically possible
  as a result of some vulnerability. After upgrading the system to fix
  this vulnerability, the system should be able to attest that it is
  now in a good state. However, if an adversary were able to use their
  priviliges to replace the credential, they are able to obtain
  persistence and the NvPCR measurements are no longer trustworthy.

This PR changes things to take a different approach. Instead of
requiring knowledge of a secret, the NvPCRs are now created in a way
that requires a policy to be satisfied for writing. The write policy has
2 branches:
- TPM2_PolicyNvWritten(true), which can be satisified without any
  further authorization if the NvPCR has already been extended.
- TPM2_PolicyAuthorize(pcrPubKey, SHA256("nvpcr-init")) which can be
  satisfied with a signed PCR policy, and must be used to perform the
  initial extend to a NvPCR.

The intention here is that the signed PCR policy that can be used to
authorize the initial extend to the NvPCR can only be satisfied during
early boot. During later boot phases, this signed PCR policy must not be
valid. This means that if a NvPCR is undefined and redefined, it won't
be possible to satisfy its write policy in order to able to perform the
initial extend.

In order to anchor the NvPCRs and prevent them from being undefined and
then redefined with a different policy that does allow them to be
extended, the names of the NvPCRs are measured to PCR9. Verifiers must
check that the names of attested NvPCRs match the measurements in PCR9.

This uses the PCR signing key from the currently booted UKI to create
the NvPCRs. If this changes between boots, then tpm2-setup automatically
recreates new NvPCRs with an updated write policy to reflect this. I've
tried to be careful to not undefine arbitrary NV indexes in this case,
so it checks that the existing NV index looks like a NvPCR (ie, it has
the expected attributes) before undefining it.

I did originally try to preserve the old behaviour for existing systems,
but it makes things a lot more complicated. As the new implementation
already creates new NvPCRs when the PCR signing key changes, I ended up
just automatically upgrading the old NvPCRs as well. Again, I check here
that any existing NV index looks like an old style NvPCR (ie, it has the
expected attributes) before undefining it.

I did notice that the initial NvPCR measurement isn't going into the
log. I don't know if that was an intentional choice, but I've preserved
that behaviour in this PR.

This also adds a new option to ukify (--sign-initrd-pcrs) which creates
signed policies (one per PCR bank) that can only be satisfied from the
initrd. These policies are used for initializing the NvPCRs, but can also
be used for protecting TPM2 keyslots enrolled with systemd-cryptenroll
(by using the --tpm2-public-key-policyref=initrd option).

There is one outstanding issue. The NvPCR definitions support different
algorithms, but the use of PolicyAuthorize means that they can only support
SHA-256 for now. This is because the signed policy algorithm must match
the name algorithm, and some additional work is required to support
signed PCR policies for algorithms other than SHA256. I've left a note in
tpm2_nvpcr_initialize that details what's required, and I'll take a look
at that in a subsequent PR.
2026-07-28 08:35:39 +02:00
Liu Zheng
0d92898e85 localed: normalize empty X11 option values to NULL after parsing
x11_read_data() parses an 'Option "XkbVariant" ""' line in
00-keyboard.conf with strv_split_full(..., EXTRACT_UNQUOTE), which turns
the empty quoted value into a non-NULL empty string rather than NULL.
Since 812aa57d2c ("string-util: beef up string_is_safe()") an empty
string is rejected by string_is_safe() unless STRING_ALLOW_EMPTY is
passed, so x11_context_is_safe() now refuses such a context and
x11_context_verify() discards the whole thing. As a result "localectl
status" reports "X11 Layout: (unset)" even though the file names a valid
layout, and compositors reading org.freedesktop.locale1 (e.g. the SDDM
greeter) fall back to the us layout.

Introduce x11_context_normalize(), suggested by @lionheartyu, which
converts empty strings to NULL while freeing the heap allocation —
unlike x11_context_empty_to_null() which only NULLs the pointer without
freeing. Call it at the end of x11_read_data(), before
x11_context_verify(), so empty option values are treated as unset. This
also keeps x11_context_equal() comparisons consistent with the setter
path (method_set_x11_keyboard) and vconsole_read_data(), which both
store NULL for empty values.

Fixes #43007
2026-07-28 11:53:11 +09:00
Rafael Passos
bf743de5aa hwdb: Fix Brazilian ABNT2 KEY_RO scancode for HP ProBook x360 435 G7 (#43151)
The physical key between right Shift and right Ctrl (Brazilian ABNT2 ["/
? deg"]) emits scancode 0x4e (KEY_KPPLUS) at boot.
    
Remap the observed 0x4e keycode to KEY_RO so it produces the expected
characters with the Brazilian ABNT2 XKB layout.
2026-07-28 11:07:48 +09:00
Alexander Egorov
f63ffc14c7 hwdb: Add accelerometer matrix for OneXPlayer Super X
The BMI260 accelerometer in the OneXPlayer Super X is exposed through
the ACPI BMI0160 ID. Its X and Y axes do not match the built-in display
axes, and no firmware mount matrix is provided.

Add an exact vendor and product DMI match with the matrix verified on
the hardware. The matrix keeps the native landscape position normal and
maps both portrait rotations to the corresponding display orientation.

Tested with iio-sensor-proxy 3.8 and Mutter 49.7 in all display
orientations. The compiled hwdb entry also matches the complete modalias
reported by the device.

Development of this patch used assistance from ChatGPT 5.6 sol.
2026-07-28 10:14:57 +09:00
Emilio Sepulveda
db3060948c po: Translated using Weblate (Interlingua)
Currently translated at 0.6% (2 of 286 strings)

Co-authored-by: Emilio Sepulveda <emism.translations@gmail.com>
Translate-URL: https://translate.fedoraproject.org/projects/systemd/main/ia/
Translation: systemd/main
2026-07-27 20:52:21 +01:00
dongshengyuan
7412c16ef8 creds: query OpenSSL for GCM tag length
Follow-up for: 21bc0b6fa1

Follow-up for: 99d0a9fdb0
2026-07-27 19:19:31 +09:00
Daniel28972897
ecc8c69eca udev: probe_superblocks: return a real negative errno on failure
Previously, probe_superblocks() forwarded blkid_do_fullprobe()'s and
blkid_do_safeprobe()'s raw return code on error, which is just -1 with
no errno attached. The caller passes this value straight to
log_device_debug_errno() with %m, so a generic probing failure always
printed strerror(-1) regardless of what actually went wrong.

Convert the -1 error case to a proper negative errno via
errno_or_else(), matching the pattern used elsewhere in this file. The
'nothing found' (1) and success (0) return values are unchanged.
2026-07-27 19:05:40 +09:00
Eric Curtin
0494ced5a9 mount-util: don't trigger automounts when cloning submounts
get_sub_mounts() clones each submount of the given prefix with
OPEN_TREE_CLONE. The kernel resolves the path of an OPEN_TREE_CLONE
with LOOKUP_AUTOMOUNT, i.e. if the submount is an autofs automount
point that has not been triggered yet, cloning it forces the automount
to trigger, and open_tree() blocks until the automount request has
been served.

This is particularly problematic during boot: setting up a private
/proc for the first sandboxed service (e.g. systemd-userdbd.service,
which uses ProtectProc=invisible) clones the submounts of /proc, which
include PID 1's own /proc/sys/fs/binfmt_misc automount point. The
executor then blocks until PID 1 gets around to dispatching the
resulting proc-sys-fs-binfmt_misc.mount job, which competes with the
ongoing boot transaction. On a Fedora 44 VM this delayed
systemd-userdbd.service by ~0.9s, and with it every early-boot NSS
user/group lookup that ends up in nss-systemd's varlink queries — most
importantly systemd-tmpfiles-setup-dev-early.service, which
systemd-udevd.service is ordered after, stalling the whole boot
critical path:

  [2.131846] proc-sys-fs-binfmt_misc.automount: Got automount request
             for /proc/sys/fs/binfmt_misc, triggered by 323 ((systemd-userd))
  [2.943574] Mounting proc-sys-fs-binfmt_misc.mount...
  [2.968507] Mounted proc-sys-fs-binfmt_misc.mount.

Triggering the automount here also defeats its purpose, since
binfmt_misc ends up mounted on every boot even if nothing ever
accesses it.

Pass AT_NO_AUTOMOUNT so that untriggered automount points are cloned
as they are instead.

Before (Fedora 44 VM, 4 vCPUs):
  Startup finished in ... + 2.559s (userspace)
    1.058s systemd-tmpfiles-setup-dev-early.service
     938ms systemd-userdbd.service

After:
  Startup finished in ... + 1.582s (userspace)
     137ms systemd-tmpfiles-setup-dev-early.service
      22ms systemd-userdbd.service
2026-07-27 19:02:12 +09:00
Luca Boccassi
bbc5511d6a test: add deb coverage and a few more sanity checks to TEST-88-UPGRADE (#43162) 2026-07-26 17:41:16 +01:00
Luca Boccassi
5578a22696 ci/mkosi: bump fedora release version to 44 (#43160) 2026-07-26 15:07:21 +01:00
Luca Boccassi
a5819bd3f5 test: udev might not be running in container, skip check in TEST-88-UPGRADE 2026-07-26 13:45:28 +01:00
Luca Boccassi
14b93b6409 test: add a few more quick sanity checks to TEST-88-UPGRADE 2026-07-26 13:45:28 +01:00
Luca Boccassi
28e1f84d6a test: add deb coverage to TEST-88-UPGRADE 2026-07-26 13:45:28 +01:00
Yu Watanabe
686ee16166 ci/mkosi: bump fedora release version to 44 2026-07-26 20:46:16 +09:00
Yu Watanabe
1acd30aa1f mkosi/sanitizers: also wrap mkfs.erofs
Fixes the following failure on Fedora 44:
```
TEST-58-REPART.sh[932]: Executing mkfs command: /usr/bin/mkfs.erofs -U 45745a56-aa2f-4619-8ca7-9cb63667c2ae -zlz4hc,level=3 /dev/loop0 /var/tmp/.#reparteb739e8b8cae7b70
TEST-58-REPART.sh[932]: Successfully forked off '(mkfs)' as PID 933.
TEST-58-REPART.sh[933]: ==933==ASan runtime does not come first in initial library list; you should either link runtime to your application or manually preload it with LD_PRELOAD.
TEST-58-REPART.sh[932]: '(mkfs)' failed with exit status 1.
```
2026-07-26 20:46:12 +09:00
Yu Watanabe
facb0c20af mkosi: drop references to EOL fedora releases 2026-07-26 20:45:43 +09:00
Yu Watanabe
ba3b1eff0b github: update placeholders in template 2026-07-26 20:42:28 +09:00
Yu Watanabe
a1e42f3438 sysupdate: fix root cleanup and default feature selection (#43154) 2026-07-26 20:28:33 +09:00
Mike Yuan
5306dca35f iovec-util: enclose macro arg in ()
Follow-up for 56f3ae9292
2026-07-26 19:58:08 +09:00
dongshengyuan
86168be51a core/namespace: split out bind mount retry helper
Move the bind mount retry path into a small helper so
apply_one_mount() no longer carries destination creation and
retry state inline.

Report destination creation and retry failures at debug level,
then return the error to apply_mounts(). The caller still reports
the final mount namespace failure with the cleaned-up mount path.
2026-07-26 19:57:43 +09:00
dongshengyuan
c8f0be5e34 shared: drop stale env-file-label source
env-file-label.[ch] was removed by 3e5320e27d
("env-file: port write_env_file() to label_ops_pre()"), which
replaced write_env_file_label() with WRITE_ENV_FILE_LABEL.

0dc39dffbd ("Use paths specified from environment variables for
/etc configuration files") later reintroduced only
src/shared/env-file-label.c. The header and meson entry were not
restored, no callers use write_env_file_label() or
write_vconsole_conf_label(), and the current write_env_file()
signature no longer matches the stale wrapper.

Remove the unbuilt source file again.

Removed by: 3e5320e27d
Reintroduced by: 0dc39dffbd
Follow-up for: 0dc39dffbd
2026-07-26 17:17:52 +09:00
dongshengyuan
bbe99a925b sysupdate: include default component for feature-all
--component-all is documented to include the default component-less
installation. Do not drop it merely because the context operates on a
root/image, or because all its transfers are currently disabled by
features.

This lets --component-all --feature-all enable-feature write the
default component feature drop-ins instead of succeeding with no
components selected.

TEST-72-SYSUPDATE covers both all transfers disabled by features and
the same default component feature operation under --root=.

Repro: create a default feata.feature plus a transfer gated by feata,
then run:
build/systemd-sysupdate --root="$root" --component-all --feature-all enable-feature

Before: no drop-in was written.

Follow-up for: 4481661a75
2026-07-26 15:26:06 +08:00
dongshengyuan
b03503a116 sysupdate: keep root-relative installdb paths absolute
When recording installdb entries under --root=, keep the leading slash
after stripping the root. Compare current transfer target paths in the
same root-relative form during cleanup.

This prevents cleanup from treating still-owned resources below --root=
as orphaned.

TEST-72-SYSUPDATE covers --root= cleanup keeping a still-owned file and
its matching installdb entry.

Repro: create a rooted transfer for /target/foo-@v.bin, add a
matching installdb entry for /target/./foo-@v.bin, then run:
build/systemd-sysupdate --root="$root" --verify=no cleanup

Before: foo-1.bin and the installdb entry were removed.

Follow-up for: d82e256bb9
2026-07-26 15:26:06 +08:00
Daniel28972897
65f62301c2 test: add coverage for systemctl preset in test-systemctl-enable.sh
Repeats the enable/disable specifier-expansion check with 'systemctl
preset' instead. preset-all is intentionally not exercised here, since
$root accumulates unit files from earlier sections that are
deliberately invalid, and preset-all would trip on those unrelated
units.
2026-07-26 15:10:33 +09:00
dongshengyuan
414777a108 sysupdate: don't double-prefix definitions with --root=
Definitions enumerated under --root= are already rooted. Passing those
paths to the config parsers with the same root prefixes the root again,
so feature and transfer files are parsed from the wrong path.

Repro: create root/etc/sysupdate.d/rootfeat.feature and
01-root.transfer, then run:
build/systemd-sysupdate --root="$root" --verify=no --offline features rootfeat

Before: parsing failed at line 1 with a bogus Source Type= error.

Fixes #42783.
Follow-up for: e1384cfb09
2026-07-26 14:40:05 +09:00
dongshengyuan
99c6f01321 veritysetup: keep parsing after ignored NvPCR options
tpm2-measure-nvpcr=no and invalid NvPCR names only affect the current
comma-separated option. They returned from parse_options(), so later
options were silently skipped.

Repro:
build/systemd-veritysetup attach testvol /dev/null /no/such \
    0000000000000000000000000000000000000000000000000000000000000000 \
    tpm2-measure-nvpcr=no,root-hash-signature=relative

Before: root-hash-signature=relative was skipped, and execution continued
to the missing block-device error.

After: root-hash-signature=relative is parsed and rejected. Invalid NvPCR
names take the same continue path.

Follow-up for: 85d7fb2247
2026-07-26 14:40:05 +09:00
dongshengyuan
47536f5aac escape: add --stdin input mode
systemd-escape currently only processes strings passed as
command line arguments. This is awkward for callers that already
have a generated list of strings, because they need to loop around
the tool or use xargs and carefully preserve whitespace and other
special characters.

Add --stdin to read one string per line from standard input and
write one escaped result per output line. Keep command line strings
mutually exclusive with --stdin so the input source remains
unambiguous.

Use an explicit option instead of treating '-' specially, since '-'
is itself a valid string to escape. The existing escape, unescape,
mangle, path, suffix, and template rules are reused unchanged.
2026-07-26 13:20:55 +09:00
Eric Curtin
5ef2510988 shared/dropin: don't re-derive drop-in name candidates per lookup dir
unit_file_find_dirs() is called once for every (unit name or alias,
lookup directory, drop-in suffix) combination while enumerating units
at boot, to check whether that unit has a ".d", ".wants", ".requires"
or ".upholds" drop-in directory in that particular lookup path. On a
typical system with ~270 loaded units and ~12 directories in the unit
search path, this adds up to tens of thousands of calls.

For every one of those calls, the function used to independently
re-derive the full chain of candidate unit names to check for that one
directory: the name itself, its template if it is a template instance,
and its "-" prefix chain (e.g. for "foo-bar-waldo.service" also
"foo-bar-.service" and "foo-.service"), recursively expanding further
where applicable. That derivation only depends on the unit name itself
and does not involve the lookup directory at all, so it produces the
exact same list of candidate names regardless of which of the 12
lookup directories is currently being checked. Despite this, it was
being fully recomputed for every single directory, doing several small
allocations and unit-name parsing calls (unit_name_template(),
unit_name_to_prefix(), unit_name_build_from_type(), ...) each time.

Split the name-derivation logic out into its own function,
unit_file_expand_dropin_names(), and compute it once per unit
name/alias, then reuse the resulting candidate list across all lookup
directories instead of re-deriving it for each of them. The order in
which candidate directories end up being added is unchanged, so this
is not expected to alter drop-in resolution behaviour: I confirmed this
by comparing the sorted unit load state, fragment path and drop-in path
output of "systemd --test --system" before and after this change on the
same unit tree, which is byte-for-byte identical.

I measured the effect by instrumenting manager_enumerate() with
CLOCK_MONOTONIC timestamps and running systemd, built from this exact
tree, as actual PID 1 in a container with ~270 real units loaded, 50
runs each before and after this change:

  before: mean 45.35ms (stddev 0.60ms)
  after:  mean 38.81ms (stddev 0.81ms)

a ~14% reduction with about 8 standard deviations of separation between
the two distributions, i.e. well outside of run-to-run noise.

unit_file_expand_dropin_names()'s out parameter is renamed from
ret_names to names, since it is appended to (including recursively)
rather than only being populated on success, matching the ret_ naming
convention used elsewhere for output-only parameters. Also, a failure
partway through expanding a name's candidates (e.g. OOM) no longer
discards the candidates already derived before the failure, keeping
unit_file_find_dirs() closer to the original recursive
implementation's error handling.

unit_file_add_dir_if_exists(), which builds the path to check for each
(lookup directory, candidate name) pair, is now the hottest remaining
part of this code: with the per-directory re-derivation gone, it is
called once for every directory/candidate combination instead of once
per candidate. It used to build that path with strjoin(name, suffix)
followed by path_join(unit_path, name_and_suffix), i.e. two heap
allocations plus path_join()'s normalization pass. Lookup paths are
already normalized (path_simplify() + strv_uniq()), so a single
strjoin(unit_path, "/", name, suffix) produces the same string while
halving the allocations and skipping the redundant normalization.
2026-07-26 05:33:22 +09:00
Armaan Sandhu
151dafcf16 ask-password: refuse agent requests with unsafe characters in prompt fields
The message, icon and id fields are written verbatim into single-line
assignments of the [Ask] section of the agent request file, so a newline in
them lets the caller append arbitrary further assignments. Agents let a later
assignment override an earlier one, so an injected Socket= line redirects the
password to a path of the injector's choosing. Validate the fields and refuse
the request instead.
2026-07-26 05:30:02 +09:00
Yu Watanabe
a8e93919c3 Minor follow-ups for recent PRs (#43148) 2026-07-25 21:08:37 +09:00
Yu Watanabe
b556e151b9 po: update Japanese translation
The commit 843bba839a dropped space after
colon, but Weblate dislikes that. Let's readd space.
2026-07-25 20:41:47 +09:00
Mike Yuan
c2624fe9a7 various: attach errno to structured logs, even if not used in msg 2026-07-25 19:37:47 +09:00
Mike Yuan
8c98dac0dc imds-generator: do not enable IMDS logic if detect_container() failed 2026-07-25 19:37:47 +09:00
Mike Yuan
37f760f787 imds-generator: use read_full_virtual_file() 2026-07-25 19:37:47 +09:00
Mike Yuan
8fa8e29656 imdsd: use free_many_charp() where appropriate 2026-07-25 19:37:47 +09:00
Mike Yuan
d5d76ddd80 Revert "basic/allow-util: make free_many non-inline"
This reverts commit 3abe1e53f6.

I remain unconvinced. The function is very short, and
by making it inline the assert()s can be optimized away.
2026-07-25 19:37:47 +09:00
Mike Yuan
89d48b71ae efi-loader: move $SYSTEMD_FORCE_MEASURE override to efi_measured_os()
Follow-up for cd911bec6e

The (debug) envvar should have highest priority, hence move it
to the new entrypoint function and give it precedence over
systemd.tpm2_measured_os=.
2026-07-25 19:37:47 +09:00
Mike Yuan
b82e739cb5 efi-loader: shorten the code a bit 2026-07-25 19:37:47 +09:00
Yu Watanabe
d20313d086 homed/fscrypt: default new homes to v2 policies (#18280) (#42397)
## Summary

Closes #18280.

`systemd-homed` currently writes fscrypt v1 policies, which bind the
master key to the calling process's keyring. This means files in a
homed-managed directory aren't readable when accessed through a
container bind mount, a different mount namespace, or by any process
other than the one that first unlocked the home. Reading the file from a
context that has the key first warms the page cache, but the underlying
problem remains.

v2 policies (Linux 5.4+) route the master key through the filesystem
keyring, via `FS_IOC_ADD_ENCRYPTION_KEY` /
`FS_IOC_REMOVE_ENCRYPTION_KEY`, so the key is visible to every process
accessing the filesystem.

This PR switches `systemd-homed` to v2 by default and keeps existing v1
homes working.

## Changes

**`shared/crypto-util`**: Add `kdf_hkdf_derive` (HKDF, RFC 5869) wrapper
around OpenSSL's `EVP_KDF` "HKDF", alongside the existing SSKDF/KBKDF
helpers.

**`homed/fscrypt`**:
- Read the existing policy via `FS_IOC_GET_ENCRYPTION_POLICY_EX`,
falling back to the legacy ioctl on pre-5.4 kernels.
- `HomeSetup` now carries a full `struct fscrypt_key_specifier` instead
of a bare 8-byte descriptor. Slot decryption derives either the v1
descriptor (double SHA-512) or the v2 identifier (HKDF-SHA512 with the
kernel's info string) from the unwrapped volume key and compares against
the policy.
- Install the master key the right way per version: `add_key("logon",
...)` to thread+user keyrings for v1, `FS_IOC_ADD_ENCRYPTION_KEY` for
v2.
- `home_flush_keyring_fscrypt` opens the image directory, reads the
policy version, and either calls `FS_IOC_REMOVE_ENCRYPTION_KEY` (v2) or
walks the user keyring (v1).
- New homes default to v2; fall back to v1 only when the kernel rejects
v2.

The on-disk slot xattr format is unchanged - the volume key is the same,
only how it binds to the directory changes. There is no v1 -> v2
migration; existing v1 homes continue to unlock, rekey, and deactivate
as before.
2026-07-25 19:36:35 +09:00
Tim Culverhouse
4517e7e4d9 core: support CollectMode in Varlink StartTransient
The io.systemd.Unit context exposes CollectMode, but StartTransient
rejects it as unsupported. This prevents Varlink clients from selecting
whether failed transient units should be garbage-collected.

Accept CollectMode when creating transient units and persist the setting
in the runtime unit configuration. Extend the integration test to verify
the value in both the Varlink response and the resulting unit.
2026-07-25 15:35:28 +09:00
logical-misha
e09402326c format-table: give mixed cell types a stable sort order (#43129)
Mixed-type cells were compared by their insertion indices, while cells
of the same type were compared by value. Combining those rules
could make `cell_data_compare()` non-transitive.

Give different non-empty `TableDataType` values a stable order. Define
empty cells as greater than non-empty cells, so they appear last in
ascending sorts and first when the order is reversed. This ensures that
the comparator defines a consistent ordering.

Fixes #43128.
2026-07-25 14:38:23 +09:00
Hilal Rahmatullah
c844a88f69 man: fix typo 2026-07-25 04:11:29 +09:00
Yu Watanabe
7cc277fb97 cryptsetup: avoid state leaks from ignored options (#43135) 2026-07-24 21:35:34 +09:00
Yu Watanabe
e6cc9d0298 tmpfiles: fix root handling and target resolution (#43031) 2026-07-24 21:15:11 +09:00
dongshengyuan
33d9f3840b cryptsetup: ignore invalid password-cache= fully
password-cache= tracks both the cache mode and whether the option was
configured explicitly. The parser set arg_password_cache_set before
validating the value, so an invalid value was logged as ignored but
still blocked the PKCS#11 default no-cache policy.

Only mark password-cache= as configured after accepting read-only or a
valid boolean.

Repro:
build/systemd-cryptsetup attach sdscan /dev/null - \
    pkcs11-uri=auto,password-cache=bogus

Before: warned ignored, then failed with the PKCS#11 cache error.
After: warned ignored, then continued to the device check.

Follow-up for: fd8ed7f26b
2026-07-24 16:38:19 +08:00
dongshengyuan
89ad718762 cryptsetup: don't keep invalid size= values
size= is specified in bits, but arg_key_size stores bytes after
parsing. The parser used arg_key_size as temporary storage before
validation. When the value was not divisible by 8, the warning said
the option was ignored, but the invalid bit count remained.

Parse into a local variable and update arg_key_size only after
validation.

Repro:
build/systemd-cryptsetup attach sdscan /tmp/plain.img /tmp/key \
    plain,size=7

Before: warned ignored, then used key size 56 bits.
After: warned ignored, then kept the default key size 256 bits.

Follow-up for: 6131a78b4d
2026-07-24 16:38:19 +08:00
dongshengyuan
3cc7ccc02c tmpfiles: inherit age-by for X entries
X entries inherit the cleanup age from the closest parent directory rule.
Inherit the age-by fields too, so parent rules such as m:1d keep their
full cleanup policy.

Reproducer:
  mkdir -p /tmp/tmpfiles-ageby/parent/{child,other}
  printf old >/tmp/tmpfiles-ageby/parent/child/file
  printf old >/tmp/tmpfiles-ageby/parent/other/file
  touch -d '3 days ago' /tmp/tmpfiles-ageby/parent/{child,other}/file
  systemd-tmpfiles --clean - <<'EOT'
  d /tmp/tmpfiles-ageby/parent - - - m:1d
  X /tmp/tmpfiles-ageby/parent/child - - - -
  EOT

Before:
  child/file remained because X used the default age-by set.
  other/file was removed by the parent m: rule.

Follow-up for 7f7a50dd15.
2026-07-24 13:44:37 +08:00
Yu Watanabe
bbd8386999 Allow arbitrary standalone progs to be installed and really stop building all standalone for tests (#43130) 2026-07-24 14:22:07 +09:00