Commit Graph
91317 Commits
Author SHA1 Message Date
David 'equinox' Lamparter 1aedc8fe5e core/service: document & improve STOPPING=1
`STOPPING=1` is final, explain in the sd_notify man page that this is
the case and log an error if a service attempts to get back out of
STOPPING with another notification.

Fixes #43465 / 98734ac74d
2026-08-24 22:46:01 +09: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
Hijae Song d669464b2a hwdb: add calibration override for AYANEO Flip KB/DS touchscreen
The Goodix Capacitive TouchScreen on the AYANEO Flip KB reports an
invalid calibration range during boot, due to unreliable I2C
communication with the touch controller early in the boot sequence.
Observed values include ABS_X max as high as 65343 and ABS_Y max as
low as 256, far outside the panel's actual resolution.

Confirmed on real hardware across multiple cold boots that the
controller never reports a correct calibration on its own, including
after forcing driver re-probes via unbind/bind. Override the axis
ranges with the panel's real resolution (1200x1920).

Also covers the Flip DS, mostly identical to the Flip KB apart from a
second screen replacing the keyboard. Not independently verified on
Flip DS hardware, but consistent with a community report of the same
Y-axis maximum (1919) for that model's main display, using a
different (and seemingly non-functional) override syntax.

Note: the panel is also mounted rotated relative to the raw sensor
axes; this entry only fixes the calibration range, not rotation (most
desktop environments handle touch rotation automatically when the
display output is rotated, independent of this).
2026-08-24 12:07:42 +01:00
Lennart Poettering 6cff583546 update TODO 2026-08-24 11:56:27 +02:00
Yu Watanabe e036040529 test-compress: extend buffer size
Otherwise, random input cases are not tested:
```
/* test_compress_decompress_blob */
/* testing xz text blob compression/decompression */
Loaded shared library 'liblzma.so.5' via dlopen().
/* testing xz random blob compression/decompression */
compression failed: No buffer space available
/* testing lz4 text blob compression/decompression */
Loaded shared library 'liblz4.so.1' via dlopen().
/* testing lz4 random blob compression/decompression */
compression failed: No buffer space available
/* testing zstd text blob compression/decompression */
Loaded shared library 'libzstd.so.1' via dlopen().
/* testing zstd random blob compression/decompression */
compression failed: No buffer space available
/* testing gzip text blob compression/decompression */
Loaded shared library 'libz.so.1' via dlopen().
/* testing gzip random blob compression/decompression */
compression failed: No buffer space available
/* testing bzip2 text blob compression/decompression */
Loaded shared library 'libbz2.so.1' via dlopen().
/* testing bzip2 random blob compression/decompression */
compression failed: No buffer space available
```
2026-08-24 03:30:52 +09: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
Christian Glombek 15458a89f1 resolved: only apply stale retention to unicast DNS cache entries
StaleRetentionSec= is a resilience feature for unicast DNS: when the
configured servers are unreachable, answering from an expired cache
entry beats answering nothing at all. That rationale does not carry
over to the link-local protocols, where there is no configured server
that could be unreachable -- peers simply come and go, and a record's
TTL is the only thing bounding how long a departed peer is still
answered for.

For mDNS the mismatch goes further. RFC 6762 treats record expiry as a
presence signal -- a host or service whose records lapse is to be
considered gone (section 10.1 goodbye packets even force this early by
publishing TTL=0), and the section 5.2 cache maintenance scheme exists
precisely so that expiry happens on time. Retaining expired mDNS
records for StaleRetentionSec= contradicts that: vanished peers linger
in the cache for the whole retention window, are served to clients as
if still present, and DNS-SD browsers do not see their services
disappear when the records' TTL lapses.

Beyond lingering entries, retention also swallows goodbyes outright, as
noted in review of the goodbye re-arm fix [1]: dns_cache_prune() and
dns_cache_expiry_in_one_second() key on the retention-extended "until",
so with StaleRetentionSec= set a goodbye's TTL=1 rewrite lands a full
retention window out -- the one-second prune of RFC 6762 section 10.1
then drops nothing, nothing re-arms, and the withdrawn service stays
listed for the whole window.

LLMNR has no goodbye mechanism, so only the lingering half applies to
it, but it does apply: dns_transaction_cache_answer() passes the
retention through for LLMNR replies just like for unicast DNS, and the
stale-serving gate in the transaction code does not look at the
protocol, so a departed LLMNR peer keeps being answered from cache for
the whole window as well.

Zero the retention centrally in dns_cache_put() for everything but
unicast DNS, which covers both put paths: transaction replies and the
mDNS packets cached directly by on_mdns_packet(). Add tests pinning
both directions, including the goodbye rewrite of an existing mDNS
entry.

[1] https://github.com/systemd/systemd/pull/43259#discussion_r3809488076
2026-08-23 17:45:51 +01:00
Jakub Stasiak 5e96efc8df test: use socat for oomd prekill hooks
Arch rolling now ships Nmap 7.991, which contains Nmap commit
b408fc2, titled "Ignore stdin with recv-only"[1].

That change omits stdin from the Ncat descriptor list in recv-only
mode. For a Unix listener, the listening socket is then its sole
descriptor. Ncat enters its listen loop only when that list has more
than one descriptor or a connection already exists, so it exits
immediately after bind and leaves the socket pathname behind.

systemd-oomd sees that stale pathname, tries to invoke the hook, and
gets ECONNREFUSED. The notification output therefore remains empty
and the jq assertion fails. The problem is visible in trunk's CI
failures[2].

Use socat for these one-way Unix listeners. It remains in accept while
waiting for the hook and is already installed in integration images.

[1] https://github.com/nmap/nmap/commit/b408fc243ce26da7ca497595833c14ce36a5e1a4
[2] https://github.com/systemd/systemd/actions/runs/32622985037/job/97153925154
2026-08-24 01:33:20 +09:00
Aleksa Sarai 44cc69769d hostnamed: expose parsed TAGS in Describe
The DBus API already exposes the parsed machine-tags list via the Tags
property but varlink clients needed to parse the raw TAGS= line from
MachineInformationData (which also required implementing tag name
validation if the tags would later be used with SetTags, to avoid
spurious errors).

So, provide the same information that DBus gets (a list of pre-parsed
tags with bad tags gracefully removed) as a new MachineTags field
returned by Describe -- this does mean that the DBus API now exposes the
same data in two ways but making Describe() consistent is more important
and mirrors the OperatingSystem* class of properties.
2026-08-23 14:10:22 +01:00
Yu Watanabe ded83144eb sd-journal: constify several arguments 2026-08-23 15:27:41 +09:00
Jakub Stasiak 354b51ddbf sd-device: ignore invalid ordinary properties
I had a situation where Dell Wyse 3040 with SK Hynix eMMC stopped booting
after upgrading from Fedora 42 to Fedora 44 with systemd 259.8.

The card reports a product name containing byte 0x92, but the kernel event
also contains the valid module alias needed to load mmc_block:

    MMC_NAME=H8G4a\222
    MODALIAS=mmc:block

I inserted the mmc_block kernel module manually and booted successfully.
Then after enabling udevd debug logging and retriggering the MMC add event
via

    udevadm control -l debug
    udevadm trigger -v -c add -s mmc
    udevadm settle

I saw the failure in the "journalctl -b -u systemd-udevd.service"
output:

    mmc0:0001: sd-device: Refusing invalid property: MMC_NAME=H8G4a\222
    mmc0:0001: sd-device: Failed to add property 'MMC_NAME=H8G4a<92>': Invalid argument
    sd-device-monitor(manager): Failed to create device from received message: Invalid argument

Since PR 41001, strict property validation returns EINVAL for the bad
MMC_NAME. device_new_from_nulstr() propagated that error and discarded
the whole event, so udev never processed MODALIAS and did not load
mmc_block.

Skip ordinary properties whose keys or values fail validation. Do not store
them, but continue processing the remaining properties. Required and typed
properties are handled separately and remain fatal when invalid, as do
malformed records and all other errors.

Closes: https://github.com/systemd/systemd/issues/42930
Related: https://github.com/systemd/systemd/issues/41339
Related: https://github.com/systemd/systemd/issues/43008
Similar: https://github.com/systemd/systemd/pull/42316
Similar: https://github.com/systemd/systemd/pull/43061
Regression: https://github.com/systemd/systemd/pull/41001
2026-08-23 13:23:32 +09:00
lucia-huang7 ed22b5a77f discover-image: rename image sidecar files from old paths
image_rename() updated the Image object name and path before
computing the source paths for auxiliary files. As a result, the
auxiliary rename loop looked for files with the new image name,
while existing sidecars such as .roothash, .verity, and
.raw.tpmstate still used the old image name.

Delay updating the Image object until after renaming its settings
and auxiliary files. This lets image_auxiliary_path() resolve
existing sidecars from the old image name while
rename_auxiliary_file() assigns the new name.

Extend the import test raw image rename coverage to check
representative sidecars are renamed together with the image.
2026-08-22 11:31:55 +09:00
Luca Boccassi cd4379bb54 nsresourced: harden the transient UID/GID write restriction (#43196)
nsresourced hands out transient, recyclable UID/GID ranges to
unprivileged user namespaces, and a BPF-LSM policy is what keeps a
client from leaving inodes owned by its transient range on a file system
that outlives the namespace, so that a later client which gets the same
range can't inherit them.

The old policy decided based on the mount a write went through, which is
forgeable: unshare(CLONE_NEWNS) gives you clones of every mount with
fresh mount IDs but the same superblock, and the mount namespace's owner
is yours to pick. overlayfs sidesteps it entirely. So this reworks the
check to look at where the write actually lands on disk.

The first commit (Christian Brauner's) replaces the per-mount allowlist
with two questions answered from fields the client can't forge and that
survive mount cloning: does the file system die together with the user
namespace (sb->s_user_ns at or below the managed one), and does the
transient ID actually reach the disk, or does an idmapped mount
translate it into something else first. It walks the userns chain
upwards so a nested namespace can't escape it. The map layout changed,
so the pins move to userns-restrict.v2 and the old ones are removed on
install.

The second commit handles overlayfs. A write through an overlay creates
the file on the upper layer via vfs_create(), which only trips the inode
LSM hooks, not the path hooks we attach to, and the one path hook that
does fire sees the overlay mount, which belongs to the managed namespace
and so looks like it dies with it even though the upper may be
persistent. So we judge the upper at mount time in sb_kern_mount and
refuse a writable overlay unless its upper dies with the namespace too.
Reading overlayfs' private ovl_fs/ovl_layer uses CO-RE type flavors
guarded by bpf_core_type_exists(), and the service now orders after
modprobe@overlay.service.

The third commit deals with restarts. The managed set only lives in the
pinned maps, so an upgrade that changes the map layout comes up with
empty maps and every already-running namespace silently loses its
restriction. manager_startup() now re-adds the live registry entries to
the maps in the same pass that reaps the dead ones. The setgroups()
denial is restored from a flag we now store in the registry.

One consequence: a managed namespace can only mount a writable overlay
whose upper dies with it, e.g. a tmpfs it set up itself. If you need a
writable persistent upperdir (mkosi does), use a plain unprivileged user
namespace for that, not a transient nsresourced range.
2026-08-21 22:05:25 +01:00
Yu Watanabe f9558beb18 resolve: add io.systemd.Resolve.Monitor.{FlushCaches,ResetServerFeatures} (#43479)
Some miscellaneous varlink migration for resolved.

These seem to fit better with the io.systemd.Resolve.Monitor interface,
so add them to that.
2026-08-22 04:43:41 +09:00
tunaichao 641c19e21e core: apply UnsetEnvironment= after command line expansion
UnsetEnvironment= was applied to the environment block before the
command line was expanded. Since the expansion looks the variables up
in that same block, any variable listed in UnsetEnvironment= was
already gone when $VAR in ExecStart= and friends was expanded, and a
whole-word $VAR reference was dropped from the command line.

Let the expansion see the full environment block, and apply the
unsetting only to the environment block passed to the executed
process. This way UnsetEnvironment= can hide variables from the
executed process without breaking command lines that reference them.

Extend the exec-unsetenvironment test accordingly: the whole-word
$VAR6 argument must be expanded into a positional parameter for the
shell, while ${VAR6-X} must evaluate to X in the executed process.

Also document in both the UnsetEnvironment= description and the
"Environment Variables in Spawned Processes" section that the
unsetting happens after command line variable expansion.

Fixes: #43343
2026-08-22 04:27:27 +09:00
Chris Ayoub 0b87becb0a core: clear dependency graph before freeing all units
When the manager tears down every unit during reload or shutdown,
unit_free() removes each dependency from both endpoints. This work is
redundant because every dependency map is about to disappear, and it
scales poorly with thousands of synthesized mount units.

Clear all unit dependency maps in one manager-wide pass before invoking
the existing unit_free() cleanup.

With 10,000 bind mounts, this reduced the mean daemon-reload time from
63.558s to 14.708s.
2026-08-22 04:21:35 +09:00
Nick Rosbrook 3a09ba33e2 resolvectl: use io.systemd.Resolve.Monitor.ResetServerFeatures
Use the new varlink method instead of dbus.
2026-08-21 11:54:32 -04:00
Nick Rosbrook 6c248546df resolve: introduce io.systemd.Resolve.Monitor.ResetServerFeatures
Add varlink version of ResetServerFeatures.

Add this to io.systemd.Resolve.Monitor, since that interface already
handles many manager related things.
2026-08-21 11:54:32 -04:00
Nick Rosbrook 85dd7a2170 resolvectl: use io.systemd.Resolve.Monitor.FlushCaches
Use the new varlink method instead of dbus.
2026-08-21 11:54:32 -04:00
Nick Rosbrook 881ab94dd0 resolve: introduce io.systemd.Resolve.Monitor.FlushCaches
Add varlink version of FlushCaches.

Add this to io.systemd.Resolve.Monitor, since that interface already
handles many cache and manager related things.
2026-08-21 10:27:03 -04:00
Michael Vogt 3bbf9351dc creds: typo fix in the Credentials.NullKeyNotAllowed description
There is small (but confusing) typo in the description of the
`io.systemd.Credentials.NullKeyNotAllowed` error. This commit
fixes it.
2026-08-21 13:04:05 +02:00
Zbigniew Jędrzejewski-Szmek 16835f02c0 Add "project" field to cli introspection data (#43430) 2026-08-21 11:27:45 +02:00
Zbigniew Jędrzejewski-Szmek 9062186b46 shared/verbs: add "project" field in introspection data
As raised in post-merge review for the addition of COMMAND, nothing in the
data specified that the program is part of the systemd project.
2026-08-21 09:12:19 +02:00
Yu Watanabe 58b0764a20 sysctl: introduce --save= and --revert= options (#43325) 2026-08-21 04:57:57 +09:00
Yu Watanabe 8c321be1fb journal: always obtain Manager object from varlink server
Previously, the userdata assigned varlink operation was Manager object or
SyncReq object, depends on if synchronization operation is queued or not.

When there is a method that sets a custom userdata, we should not
inherit the userdata of sd_varlink_server to sd_varlink.

Let's drop SD_VARLINK_SERVER_INHERIT_USERDATA flag from the server,
and always obtain the Manager object from the server.

Follow-up for c2806a8c1d.
2026-08-21 04:56:28 +09:00
Chris Coulson 7ecc970249 tpm2: add missing dlopen_libcrypto
tpm2_tpmt_signature_to_pem uses openssl functions directly, so it needs
to ensure that it is dlopened.
2026-08-21 03:08:31 +09:00
dongshengyuan 83e9162b93 logind: preserve scheduled shutdown on failure
Do not discard an existing scheduled shutdown until the new action
has been accepted. Keep failed D-Bus and Varlink requests from
cancelling the pending shutdown.

Follow-up for: 5ed73478e1
2026-08-21 03:04:25 +09:00
Yu Watanabe 5e2d9c6ed1 man: document systemd-sysctl --save= and --revert= 2026-08-21 00:50:02 +09:00
Yu Watanabe 80e346af74 test: add test cases for systemd-sysctl --save= and --revert= 2026-08-21 00:48:25 +09:00
Yu Watanabe fb19c2ffa2 sysctl: introduce --revert= option to remove runtime sysctl config
This may be useful for removing files created by the --save= option.
2026-08-21 00:46:17 +09:00
Yu Watanabe 45bd015441 sysctl: add --save= option to save loaded settings
This may be useful for saving sysctl settings provided on the command line,
via standard input, or with --inline.
2026-08-21 00:45:13 +09:00
Yu Watanabe 1c223728cf sysctl: skip leading whitespaces and ignore arguments start with '#' when --inline 2026-08-21 00:40:53 +09:00
Yu Watanabe 5c76cb0e27 sysctl: --inline requires positional arguments 2026-08-21 00:40:53 +09:00
Chris Coulson 768b6f21ec report: Add a TPM2 signing backend
This adds an initial TPM2 implementation of the io.systemd.Report.Signer
interface, which returns a set of signed TPM attestations that also
includes the supplied report digest.

The returned report consists of multiple components:
- A signed PCR quote generated with TPM2_Quote.
- Signed NvPCR attestations generated with TPM2_NV_Certify.
- A signed audit session attestation generated with
  TPM2_GetSessionAuditDigest.

Each signed report component includes the JSON encoded TPMS_ATTEST
attestation structure and corresponding signature, in both PEM encoded
form and as a JSON encoded TPMT_SIGNATURE structure.

NvPCR report components also include the readable name of the NvPCR, the
NV index public area as the JSON encoded TPMS_NV_PUBLIC structure, and some
additional authenticated data that is digested and supplied as the
qualifying data to the TPM2_NV_Certify command. This authenticated data
includes the NvPCR name and priority.

The report digest that is supplied via varlink is supplied as the
qualifying data to the audit session attestation.

The returned report also includes the event log which is retrieved from
pcrlock's varlink interface, and the public area of the signing key in
both PEM encoded form and as a JSON encoded TPMT_PUBLIC structure.

The audit session attestation is always the last component. The
preceding components are all executed with the audit session, and the
signer requires the audit session to remain exclusive whilst generating
the report. What this does is provide evidence to a verifier that the
overall report is a single, consistent snapshot of the system (ie, no
other TPM commands executed whilst generating the report) because the
audit session attestation contains a field that indicates that the
session was exclusive at the time it was attested.

The set of attested PCRs and NvPCRs are currently hardcoded. It includes
all firmware PCRs with the exception of PCR6, and all other PCRs with
the exception of the IMA one (which isn't useful on its own without the
IMA log). All defined NvPCRs are included.

A verifier can verify the signed attestation components individually by
verifying their signatures against the supplied attestation data, using
the supplied public key.

For the PCR report component, a verifier can replay the measurements in
the log in order to reconstruct the PCR values, and then use this and
the PCR selection from the attestation in order to calculate the PCR
digest, and then check that this matches the one in the attestation.

For the NvPCR report components, a verifier checks that the NV index
name in the attestation matches one that is anchored in PCR9 to be sure
that the attestation is for a valid NvPCR. A verifier can then replay
the measurements in the log to ensure that the resulting NvPCR value
matches the one supplied in the attestation. The authenticated data is a
JSON blob containing the NvPCR name and priority. A verifier can digest
this and ensure it matches the qualifying data in the attestation.

The audit session attestation includes the audit session digest and
whether the audit session was still exclusive when the attestation was
generated. A verifier should confirm exclusivity. The digest includes a
record of all TPM commands executed with the audit session, as each
command results in it being extended with the command parameter hash and
the result parameter hash. A verifier should replay the preceding report
components to compute an expected audit digest and make sure that this
digest matches the one in the attestation in order to be sure that the
overall report represents a single, consistent snapshot. The other
report components provide sufficient information for a verifier to
reconstruct the cpHash and rpHash.

When reconstructing the cpHash for the PCR and NvPCR components, the
signing scheme is the NULL scheme (they use the attestation key's
signing scheme). The required signing key public area is supplied in
the report. The supplied qualifying data is in the extra data field of
the attestation.

The PCR selection is also required to reconstruct the cpHash for the
PCR component. The PCR selection is available in the attestation.

The name of the NV index is also required to reconstruct the cpHash for
the NvPCR components. The name is available in the attestation.

The rpHash for each component can be reconstructed from the supplied
attestation blob and signature.

In the future, we might want to add more report component types. Eg, we
could add report components for ordinary NV indexes. Using the audit
session means that we could also add additional components that the TPM
can't attest directly, such as the values of interesting TPM properties
(as the TPM2_GetCapability calls will appear in the audit session digest).

The attestation signing key is stored as a JSON file in the report
signer's state directory. Different types of keys are supported:
- Ordinary keys that are protected by an existing persistent TPM key
  such as the SRK or EK.
- Persistent TPM keys.
- Primary keys, which are recreated using a template on use.

When an ordinary or primary key is used, the report signer saves the
object context in its runtime directory. This context is used on future
invocations. This has the benefit that where a primary key is used, it
doesn't need to be recreated on each use. When an ordinary key is used,
we don't need to run TPM2_Load, which requires authorization with the
parent key, on each This authorization currently requires a policy
session for low-range EKs.

Regardless of the key type, it must be a restricted signing key. If no
key exists, an ordinary key is generated automatically.

The attestation key can also have an associated credential which is
attached to the signed report. The credential can be issued by a CA or
some other party during onboarding, and is presented to a verifier as
proof that the attestation key is authentic. It is considered an opaque
blob in order to not require it to be a specific format, such as a X.509
certificate. I've called this a "voucher" though because "cred" or
"credential" has other meanings in systemd.

As a follow-up to this, I plan to add a varlink interface for creating
attestation keys that can be used for report signing.
2026-08-20 15:30:20 +02:00
Stephanie Wilde-Hobbs ac80a8f4f3 hwdb: label Lenovo ThinkPad X1 Tablet Gen 3 trackpoint as pointing stick
The trackpoint of the ThinkPad X1 Tablet Gen 3 detachable keyboard (USB
17EF:60B5) lives in the same HID interface as the touchpad, which is
bound to hid-multitouch. The kernel never sets INPUT_PROP_POINTING_STICK
for it, so input_id classifies the trackpoint as a plain mouse.

Mark it as a pointing stick so libinput applies trackpoint acceleration
instead of the mouse acceleration profile.

The interface also exposes a second mouse node without a middle button;
the modal match keys on the button set (k110,111,112) to select only the
trackpoint node and leave the touchpad and the other mouse node
untouched.
2026-08-20 04:53:28 +09:00
Andrew Dunn 8e3d6dc535 crypto-util: zero-pad ECC point coordinates to curve width
ecc_pkey_to_curve_x_y() marshalled the affine point coordinates with
BN_num_bytes() + BN_bn2bin(), which produce the minimal big-endian
encoding and strip any leading zero bytes. The affine coordinates are
elements of the curve's underlying field, though, and consumers expect
them at the fixed field width.

About 1 in 256 keys per coordinate has a most significant zero byte on
the curves whose field width is a whole number of bytes, and about 1 in 2
on P-521, where only the low bit of the leading byte is ever set. The
coordinate then comes out one or more bytes short of the field width. When
that happens tpm2_tpm2b_public_from_openssl_pkey() builds a TPM2B_PUBLIC
whose unique.ecc.x or .y is undersized. The TPM 2.0 reference
implementation requires each coordinate size to equal the key size in
bytes, so TPM2_LoadExternal() rejects the public area with TPM_RC_KEY.
The name a TPM derives for the object also stops matching the name
systemd computes in software, because the name hashes the marshalled
public area.

For a signed PCR policy the key is only round-tripped through the TPM at
unlock time, so an enrolled key with a leading-zero coordinate is
accepted by systemd-cryptenroll and systemd-measure and only fails when
the volume is first unlocked, with:

    Esys_LoadExternal() Esys Finish ErrorCode (0x000002dc)
    Failed to unseal secret using TPM2: State not recoverable

Derive the curve's field width from the EC group degree and zero-pad both
coordinates to it with BN_bn2binpad(). Padding a full-width coordinate is
a no-op, so only keys that a reference-conformant TPM rejects today change
their marshalling; no enrollment that currently unlocks changes behavior.
Every caller of this converter inherits the fix, including the
systemd-creds public-key binding.

Because the width now comes from the group rather than from the BIGNUM
being written, BN_bn2binpad() can fail where BN_bn2bin() could not, so
both calls return -EIO rather than asserting. It reports that through its
return value without touching the OpenSSL error queue, so these use
log_debug_errno() rather than log_openssl_errors(). EC_GROUP_get_degree
is file-local, matching the other libcrypto symbols used only here.

The tests pin the full expected coordinates for a P-384 key and a P-521
key that each have a leading zero byte. test-tpm2 gains a case pinning
the TPM object name for the P-384 key, because the name is derived from
the marshalled public area and this change alters it for exactly those
keys a reference-conformant TPM rejects today.
2026-08-20 04:06:04 +09:00
r-vdp dc4108c43c network: re-solicit RAs when the link MAC changes
A MAC change can mean the link joined another network, e.g. on an
active-backup bond failover with FailOverMACPolicy=active. NDisc only
solicits when it starts, so IPv6 sat stale until the next unsolicited
RA. Restart NDisc to solicit immediately.
2026-08-20 04:05:12 +09:00
Stephanie Wilde-Hobbs fc08ae472c hwdb: mark Lenovo ThinkPad X1 Tablet Gen 3 touchpad as internal
Similar to d13c07ecd8 and 373a4020d5, 65-integration.rules sets
ID_INPUT_TOUCHPAD_INTEGRATION=external, and libinput skips
disable-while-typing (DWT) for the device.

The touchpad is integrated into a detachable keyboard which isn't usable
on other devices so it should be marked as internal. This enables palm
detection and DWT.
2026-08-20 04:04:16 +09:00
Yu Watanabe e67956f31c Another batch of conversions to COMMAND and additions of --introspect-cli (#43436)
This is another batch of straightforward conversions. I wanted to do
udevadm here too, but it requires some design work.
2026-08-20 01:41:53 +09:00
Yu Watanabe d971596a02 verbs: fix typo
Found by Fossies.

Follow-up for 7ea090f41b.
2026-08-19 22:58:22 +09:00
Yu Watanabe 6e652b53c6 man: expand documentation for systemd-sysctl --verify
Follow-up for 0b9ac2e675.
2026-08-19 11:01:40 +02:00
Zbigniew Jędrzejewski-Szmek ebd9040b30 Fix memleak and double free in varlink methods (#43431) 2026-08-19 10:58:40 +02:00
Zbigniew Jędrzejewski-Szmek 963b2323ef report-sign-tsm: convert to VERB_COMMAND and add --introspect-cli
The custom help() is replaced by a COMMAND() description, and
--introspect-cli is added. The abstract is now wrapped automatically.
2026-08-19 08:21:30 +02:00
Zbigniew Jędrzejewski-Szmek 8d8cf2cf1a report-sign-plain: convert to VERB_COMMAND and add --introspect-cli
The custom help() is replaced by a COMMAND() description, and
--introspect-cli is added.
2026-08-19 08:21:30 +02:00