The --attr-match= and --attr-nomatch= filters are documented as
FILE[=VALUE], like the trigger filters.
Accept a bare attribute name for sysfs attribute presence matches.
Reproducer:
udevadm info --export-db --attr-match=ifindex
Before:
Expected <ATTR>=<value> instead of 'ifindex'
Follow-up:
a6b4b2fa01
When input_id prints a decoded capability bitmap, an all-zero
bitmap can decrement the index to zero.
Check the index before reading bitmask[val - 1].
Reproducer:
udevadm test-builtin input_id with an all-zero capability mask
Follow-up:
912541b024
tpm2-util.h includes crypto-util.h, which requires OpenSSL compiler
flags when HAVE_OPENSSL is defined. Add libopenssl_cflags to every
build target that uses tpm2_cflags but was missing the transitive
OpenSSL dependency.
The current TPM2 PIN mode is flawed as a compromised TPM directly exposes
the sealed secret which is the LUKS volume key itself (#27502 and #37386).
Goal: add Argon2id-based PIN hardening to TPM2 enrollment, making
the TPM a second factor rather than a single point of failure:
1. Password + salt -> Argon2id -> 512-bit key split into Key1 + Key2
2. Key2 (base64-encoded) is used as the PIN to seal a random secret
in the TPM
3. Key1 + unsealed secret -> HKDF-SHA256 -> final LUKS volume key
This implementation ensures that if the TPM is compromised, an attacker
still needs the password to derive Key1 and combine it with the unsealed
secret.
The --tpm2-with-pin= option now accepts three values:
- false (no PIN used)
- true (PIN hardened with Argon2id - default)
- "direct" (legacy PIN without Argon2id for backward compatibility)
Argon2id parameters are customizable via:
--tpm2-argon2id-memory=
--tpm2-argon2id-iterations=
--tpm2-argon2id-parallelism=
--tpm2-argon2id-iter-time=
These default to a function of available CPUs and physical memory, with
a benchmark that scales iterations to the target time (default: 2s) and
falls back to ARGON2ID_PARAMETERS_DEFAULT (64 MiB, 8 iter, 4 lanes) when
auto detection fails.
Also if the runtime OpenSSL lacks Argon2id support (< 3.2), the feature
silently falls back to direct PIN mode with a warning.
Added includes:
- src/cryptenroll/cryptenroll.c: cpu-set-util.h, limits-util.h, time-util.h
for Argon2id benchmark auto-tuning (cpus_online, physical_memory_scale,
now/usec_t)
- src/cryptenroll/cryptenroll-tpm2.c: crypto-util.h for Argon2IdParameters
struct in load_volume_key_tpm2()
- src/shared/tpm2-util.h: crypto-util.h for Argon2IdParameters in
tpm2_make_luks2_json() API
- src/shared/tpm2-util.c: limits-util.h, tpm2-util.h for physical_memory() validation
of Argon2id memory cost and function prototypes
- src/cryptsetup/cryptsetup-tokens/luks2-tpm2.c: crypto-util.h for
kdf_argon2id_derive()/kdf_hkdf_sha256() on the token unlock path
We can't make a lot of restrictions here, since users are allowed to
basically freely pick their user names and UIDs too. But let's at least
exclude system UID ranges and those beyond the 16bit range.
When doing a userdb lookup we might end up issuing a lot of IPC calls in
parallel to backends and cause them all to do work, with us waiting for
it. Let's optimize this a bit, and indicate on the socket inodes via
xattrs hints which kind of records are provided by a backend. That way
we can suppress lookups to them and optimize runtime behaviour.
This only works on Linux 7.1 and newer where socket inodes gained
support for extended attributes.
This are to the existing sd_varlink_call_and_upgrade() what
sd_varlink_callb() and sd_varlink_callbo() are to sd_varlink_call():
they put together an object on the fly, via the usual JSON builder
logic.
Add a testcase that browses all interfaces (ifindex=0) and asserts zero
'removed' events arrive while every publisher stays up. Before the
combined-answer reconciliation this flapped added/removed continuously for
services present on another interface.
We often forget to run this command when updating manpages, and notice
only much later. Add a step in the CI to flag it, as we already do for
the D-Bus docs.
When a BrowseServices subscription uses ifindex=0 ("all interfaces"),
mdns_browser_revisit_cache() looked up each mDNS scope's cache separately
and called mdns_manage_services_answer() once per scope. That function
derives "removed" events by diffing the browser's *global* service list
(all interfaces, filtered only by owner family) against the single answer
it is handed. So with two or more mDNS-relevant interfaces of the same
family, a service present on interface A is not contained in interface B's
answer and is therefore spuriously removed (emitting "removed") while B is
reconciled, then re-added (emitting "added") on the next revisit tick.
The result is a continuous added/removed/added/removed flap, within a
second, for a service that is still present and without any goodbye packet
involved -- as reported for the mDNS/DNS-SD browsing API.
Fix it by accumulating the pruned cache answers from every matching mDNS
scope into a single combined answer and reconciling exactly once, so the
removed pass diffs the global service list against the union across all
interfaces. Each scope's cache is still pruned before lookup, so genuinely
expired records still drop out of the union and real removals still fire.
The items are merged with dns_answer_add_full() rather than
dns_answer_extend(), so each item's ifindex, flags, rrsig and cache-expiry
"until" are preserved. dns_answer_extend()/dns_answer_merge() are not
expiry-aware and do not carry the source items' "until" through: it
defaults to USEC_INFINITY (the "no expiry" sentinel), which would skew the
RFC 6762 section 5.2 TTL maintenance schedule that
mdns_manage_services_answer() derives from item->until.
The single-interface (ifindex>0) path is unchanged.
Cache the IPv6 enabled state while sizing and filling NSS result
buffers, so a transient sysctl read result cannot change the tuple or
address layout after the scratch buffer size has been computed. Also
zero-initialize gaih_addrtuple records before filling IPv4 addresses.
Follow-up for e8a7a31539
Automatic key modes tolerate a failed TPM2 sealing attempt and
fall back to a host or null key. Do not consume TPM2 blob output in
that case, tpm2_seal() leaves it empty on failure, so the fallback
path should continue without TPM2 metadata.
Follow-up for 9e4379945b
NDisc packets received through the socket path are filtered before
parser dispatch, but parser entry points should still reject malformed
packet bytes instead of asserting on them. Return EBADMSG for non-zero
ICMPv6 code values in RA, NA, and Redirect messages.
Follow-up for c34cb1d645
Follow-up for 696eb2b8de
Follow-up for 44e8cf303b
An OCI index redirect already carries the digest of the selected
manifest. Store it in the expected checksum field so pull-job
verifies the downloaded manifest instead of overwriting the digest
with the computed checksum before comparison.
Follow-up for a9f6ba0496
efi_get_variable() allocates one byte for probing whether efivarfs
has grown since fstat(), then three more bytes for NUL termination.
Account for both sizes separately so a full readv() result is treated
as concurrent growth and retried before the terminators are written.
Follow-up for ab69a04600
When MACAddress= is unspecified, a stable MAC is generated to seed a newly
created netdev. Since existing netdevs are reconfigured on reload/restart,
this seed got re-applied to an already existing interface, conflicting with
an explicit MACAddress= from the matching .network file and flipping MAC.
Now, when MACAddress= is unspecified, only generate a new address if
addr_assign_type is not NET_ADDR_SET (i.e. not already set by userspace). On
first creation the interface does not exist yet, so this is a no-op and the
address is generated as before. Mirrors src/udev/net/link-config.c.
Fixes: #42457
Stores the TPM2 SRK within the credential header, allowing for parameter decryption to be utilized when decrypting the credential.
A new dimension is added to the credential ID matrix to encode this capability.
This also allows for usage of TPM2-bound credentials when a TPM owner password is set since `Esys_CreatePrimary` is no longer used for sealing credentials.
When encrypting with the `--with-key=null` option systemd-creds
is currently doing the encryption via IPC. This is not needed
for the null key, no privs are required so we can just do the
in-process operation. So instead simply check for the null-key and
if its requested use the in-process path.
* b322b8d98e Install new files for upstream build
* 3fd1b81c94 Update changelog for 261.1-3 release
* 8f95f1370c Move modules-load from systemd package to udev package
* bcdf90c670 debian/libpam-systemd.postinst: pam-auth-update does not use getopt
* 743e3399ac d/README.source: document policy for adding new binary packages
* cbea74783c Install new files for upstream build
* ef267b3ad6 debian/libpam-systemd.postinst: run pam-auth-update with --root=$DPKG_ROOT
* 54df2859b4 d/t/upstream: use mkosi from archive for Ubuntu autopkgtest
* 21959e8a59 Fix zsh installation path, again
* f01dddb047 Fix zsh installation path
* e31737edc4 Install new files for upstream build
* ca0630a51e Update changelog for 261.1-2 release
* 1ebb987599 d/t/control: pull in cpio for upstream suite
* fcf5a24f47 Two more fixups for d/copyright
* 6ad198086d d/t/control: pull new packages in upstream test suite
* bb9fd757fd Make systemd actually temporarily depend on systemd-tpm
These are the next 3 commits from #42651. Split out again, in the hope
to get a review from claude.
ptal.
full test suite and docs are in #42651. test suite passed there.
This PR only sets the default to "relaxed" - I can change the default
to "tofu" if desired. But for that we will also need to update the NEWS
file to ensure everyone is aware of this new default.
---
This PR adds a new `systemd.credentials-boot=` kernel
commandline that allows to control if credentials with
a `null` key are accepted.
The possible options are:
* strict: always insist on tpm encryption
* tofu: allow null encryption in firstboot mode and when no tpm is
available
* relaxed: allow null encryption when sb is off, or no tpm is available
* off: allow null encryption always
The default is `relaxed` which is exactly the behavior we had before.
This replaces the initial idea of using plaintext credentials
at firstboot (thanks to Lennart for this nicer and simpler design).
---
With that we can drop `- firstboot: optionally accept credentials at
firstboot without authentication` from TODO.md
Extend real_has_cpu_with_flag to support aarch64 CPU Features using
hwcaps.
With this PR, users can find out if their Arm system supports
architecture-specific features such as BTI as follows:
```
$ systemd-analyze condition 'ConditionCPUFeature=bti'
```
These are philosophically similar concepts: one deletes old versions
based on whether they are old, and the other deletes old files based on
whether they are orphaned, let's list them together.
These do what updatectl's verbs of the same name does, but are
implemented as low-level concepts in sysupdate itself.
(The idea is to eventually wrap this in Varlink IPC, and make updatectl
use them that way.)
Let's switch to string_is_safe(), and make this available to the rest of
the sysupdate sources too.
This both relaxes and tighten the rules slightly. i.e. control character
and stuff are no longer allowed, but valid UTF-8 (as opposed to ASCII)
now is.
This is currently effectively not supported (as we sometimes prefix the
definitions path with root and sometimes not), let's make this official
for now and refuse it. We could in theory support the combination but I
don't see the big benefit of it for now, hence let's just refuse it.
When we have two match patterns, e.g., because the repository layout
changed and we look for old and new style files, we can have the case
that one pattern suggests a descend into a subdir but the other pattern
would be a direct match. This was missed and only the descent was done.
Yet the other way round also has to be covered: We can't just use the
direct match because it might be that it's rejected if the type doesn't
fit (directory vs. regular file). In this case we should still descent.
Remember that we want to descend but continue checking the other
pattern first to maybe get a direct match. Introduce a new combined
return code YES_AND_RETRY to give the full information to the caller
which now can decide to fallback to a descent. While at it, use the
stat info for the directory check. Also add tests to ensure that the
order of patterns doesn't matter and we handle the above corner cases.
While for sysupdate it's fine to consume a large set of all possible
update payloads in a single directory this is not so handy for managing
and serving the update payloads. Since this large update folder is not
where the build output directly gets written to one has to create
copies and later possibly delete this added set of files.
Support matching for filenames in subdirectories by having a new **/
match pattern prefix which matches any number of nested subdirectories
or no subdirectory at all. For simplicity it's only allowed at the start
of a pattern and not a regular wildcard as the rest because the main
use case is to descend into subdirectories and only do the pattern
matching for the basenames. This way one can create a SHA256SUMS file
in the top folder and have it include all update payloads from the
release-specific (or arch-specific) subdirectories. Something similar
was already supported for directory sources where the match pattern can
start with a subdirectory path. Do also support this for SHA256SUMS for
parity while we are at it. Having the new wildcard makes mirroring also
easier because one does not have to follow the exact subdirectory layout
and one can filter by folder instead of by filename. It also makes it
possible to point the same transfer files with the new wildcard to
either a SHA256SUMS file that uses release-specific (or arch-specific)
subdirectories and includes all versions or to a SHA256SUMS file as
generated from mkosi that does not use subdirectories because it only
has files for a single version.
With the upcoming UAPI.16 JSON format we will also be able to encode
subdirectories and it makes sense to add this to SHA256SUMS for being
able to convert them. It also supports custom URLs for each entry which
is more powerful than the (arbitrary) subdirectory feature used here but
subdirectories have the advantage that they don't break mirroring.
This change also fixes the existing subdirectory handling bugs where
everything greater than two subdirectory levels failed to work because
rel_joined instead of de->d_name got used, symlinks were followed, and
we would continue silently on non-ENOENT errors.
Adds dm-clone device setup at boot via a new /etc/clonetab config file,
following the crypttab/veritytab pattern.
- Add systemd-clonesetup-generator to parse /etc/clonetab and generate units.
- Add systemd-clonesetup binary to create/remove dm-clone devices via ioctl.
- Add clonesetup.target for ordering dm-clone activation at boot.
- Add region_size= option in clonetab to configure dm-clone hydration granularity.
- Add clonetab(5) and systemd-clonesetup-generator(8) man pages.
Fixes: https://github.com/systemd/systemd/issues/39500
Commit 9b917abe02 (udev-builtin:
simplify code a bit) changed builtin lookup from copying the first
command word and comparing it with streq() to comparing only the first
command word length with strneq().
That made prefixes such as "k" or "key" resolve to the "keyboard"
builtin, depending on the builtins table order. This was not the
original behavior.
Require the matched builtin name to end at the first command word
boundary so only complete builtin names are accepted. Arguments after
the builtin name continue to work as before.