A calendar timer that is already waiting keeps the base timestamp it was
last armed from. When the wall clock is set backwards, that base can end
up in the future relative to the new realtime, and passing it to
calendar_spec_next_usec() schedules the next elapse relative to the old
future time instead of recalculating from now. systemctl list-timers
then keeps showing the stale pre-adjustment elapse (e.g. "3 years left"
after the clock moved back two years) and the timer never catches up.
Clamp the selected calendar base to the current realtime before asking
calendar_spec_next_usec() for the next occurrence. The clamp only kicks
in when the base is genuinely in the future, so Persistent=yes timers
whose last trigger is still in the past keep their catch-up behaviour and
we don't reintroduce the missed-run regression seen after suspend.
Fixes#6036.
fscrypt v1 policies bind master keys to the calling process's keyring,
which 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 a file from outside such a context first warms the buffer cache
and papers over the symptom (#18280), but the underlying problem (the
key not flowing across keyrings) remains.
v2 policies (Linux 5.4+) route master keys 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.
Switch homed to v2:
- Read the existing policy via FS_IOC_GET_ENCRYPTION_POLICY_EX, which
reports both v1 and v2 policies. The ioctl is available since Linux
5.4, i.e. on every kernel we support (our baseline is 5.10), so no
fallback to the v1-only FS_IOC_GET_ENCRYPTION_POLICY is needed.
- Drive slot matching off a full fscrypt_key_specifier (HomeSetup now
carries that instead of a bare 8-byte descriptor). Slot decryption
derives either the v1 descriptor (SHA-512 double hash) or the v2
identifier (HKDF-SHA512 with the kernel's info string), 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, looks up the
policy, 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 if the kernel rejects
FS_IOC_ADD_ENCRYPTION_KEY with ENOTTY/EOPNOTSUPP. The v2 create path
derives the identifier locally first, passes it to ADD_KEY as
expected_identifier, and cleans up via REMOVE_KEY if SET_POLICY then
fails, so the v1 fallback never sees a stranded key. Existing v1
homes continue to unlock, rekey, and deactivate as before.
- A v2 master key installed to work on an inactive home is always
removed again unless that home ends up activated. v2 keys persist in
the filesystem keyring until removed explicitly (v1 keys instead died
with the homework process' keyring), so a key left behind would leave
a home nobody activated readable until the next deactivation or reboot.
home_setup_fscrypt() and home_create_fscrypt() therefore arm a rollback
right after installing the key; the activation path disarms it once the
mount is in place (the live home owns the key), while every other path
-- create, and passwd/update/resize of an inactive home, plus all error
paths -- rolls it back via home_setup_done(). Activation reinstalls the
key.
The v1 and v2 on-disk policy formats differ (v1: 8-byte descriptor;
v2: 16-byte identifier) and fscrypt has no in-place upgrade path, so
a v1 home is always unlocked via the v1 code path and a v2 home is
always unlocked via the v2 code path, regardless of kernel version.
Slot xattr format is unchanged: the master key is the same, only how it
binds to the directory changes.
Fixes#18280.
Ananth Bhaskararaman antsub@gmail.com
Mirrors the existing kdf_ss_derive / kdf_kb_hmac_derive helpers, wrapping
OpenSSL's "HKDF" EVP_KDF. Inputs and output are passed as struct iovec;
salt and info are optional (pass NULL or an empty iovec to omit). If
salt is omitted HKDF substitutes HashLen zero-bytes per RFC 5869.
The digest is a parameter now, so reimplement the existing SHA256-only
kdf_hkdf_sha256() as a thin wrapper around the new helper, keeping the
OpenSSL HKDF plumbing in one place.
Add test vectors against RFC 5869 Appendix A.1 and against the kernel's
fscrypt v2 master-key identifier construction (HKDF-SHA512 with empty
salt and info "fscrypt\x00\x01"), so future consumers can rely on the
helper matching that exact derivation.