diff --git a/TODO b/TODO index 0f738b95bf6..07701ee7df0 100644 --- a/TODO +++ b/TODO @@ -205,9 +205,6 @@ Features: 2nd key derived from volume key of the user, with which to wrap all keys. maintain keys in kernel keyring if possible. -* add ConditionSecurity=stub-measured or so that checks if we are booted with - systemd-stub and its measurements - * sd-boot should probably measure its configuration file to PCR 5 at boot, as per TCG PC Client Platform Firmware Profile Spec. diff --git a/man/systemd.unit.xml b/man/systemd.unit.xml index ae470ee96e8..fa867dba1ac 100644 --- a/man/systemd.unit.xml +++ b/man/systemd.unit.xml @@ -1479,11 +1479,67 @@ ConditionSecurity= ConditionSecurity= may be used to check whether the given - security technology is enabled on the system. Currently, the recognized values are - selinux, apparmor, tomoyo, - ima, smack, audit, - uefi-secureboot, tpm2 and cvm. - The test may be negated by prepending an exclamation mark. + security technology is enabled on the system. Currently, the following values are recognized: + + + Recognized security technologies + + + + + + + + Value + Description + + + + + selinux + SELinux MAC + + + apparmor + AppArmor MAC + + + tomoyo + Tomoyo MAC + + + smack + SMACK MAC + + + ima + Integrity Measurement Architecture (IMA) + + + audit + Linux Audit Framework + + + uefi-secureboot + UEFI SecureBoot + + + tpm2 + Trusted Platform Module 2.0 (TPM2) + + + cvm + Confidential virtual machine (SEV/TDX) + + + measured-uki + Unified Kernel Image with PCR 11 Measurements, as per systemd-stub7. + + + +
+ + The test may be negated by prepending an exclamation mark.
diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c index a7577d8113b..1c3f29e6131 100644 --- a/src/cryptsetup/cryptsetup.c +++ b/src/cryptsetup/cryptsetup.c @@ -824,7 +824,7 @@ static int measure_volume_key( return 0; } - r = efi_stub_measured(LOG_WARNING); + r = efi_measured_uki(LOG_WARNING); if (r < 0) return r; if (r == 0) { diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c index 0a30f8c9c90..5a5c05df0c2 100644 --- a/src/fstab-generator/fstab-generator.c +++ b/src/fstab-generator/fstab-generator.c @@ -650,7 +650,7 @@ static int add_mount( } if (flags & MOUNT_PCRFS) { - r = efi_stub_measured(LOG_WARNING); + r = efi_measured_uki(LOG_WARNING); if (r == 0) log_debug("Kernel stub did not measure kernel image into PCR, skipping userspace measurement, too."); else if (r > 0) { diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c index 2bcb887a82e..d7747406228 100644 --- a/src/gpt-auto-generator/gpt-auto-generator.c +++ b/src/gpt-auto-generator/gpt-auto-generator.c @@ -106,7 +106,7 @@ static int add_cryptsetup( * assignment, under the assumption that people who are fine to use sd-stub with its PCR * assignments are also OK with our PCR 15 use here. */ - r = efi_stub_measured(LOG_WARNING); + r = efi_measured_uki(LOG_WARNING); if (r == 0) log_debug("Will not measure volume key of volume '%s', not booted via systemd-stub with measurements enabled.", id); else if (r > 0) { diff --git a/src/pcrextend/pcrextend.c b/src/pcrextend/pcrextend.c index 358bee72b08..8c5631babbd 100644 --- a/src/pcrextend/pcrextend.c +++ b/src/pcrextend/pcrextend.c @@ -351,7 +351,7 @@ static int run(int argc, char *argv[]) { length = strlen(word); /* Skip logic if sd-stub is not used, after all PCR 11 might have a very different purpose then. */ - r = efi_stub_measured(LOG_ERR); + r = efi_measured_uki(LOG_ERR); if (r < 0) return r; if (r == 0) { diff --git a/src/shared/condition.c b/src/shared/condition.c index 06fcd71be58..d3446e8a9da 100644 --- a/src/shared/condition.c +++ b/src/shared/condition.c @@ -28,6 +28,7 @@ #include "cpu-set-util.h" #include "creds-util.h" #include "efi-api.h" +#include "efi-loader.h" #include "env-file.h" #include "env-util.h" #include "extract-word.h" @@ -692,6 +693,8 @@ static int condition_test_security(Condition *c, char **env) { return has_tpm2(); if (streq(c->parameter, "cvm")) return detect_confidential_virtualization() > 0; + if (streq(c->parameter, "measured-uki")) + return efi_measured_uki(LOG_DEBUG); return false; } diff --git a/src/shared/efi-loader.c b/src/shared/efi-loader.c index 7cbd69bfb0a..0822364535e 100644 --- a/src/shared/efi-loader.c +++ b/src/shared/efi-loader.c @@ -238,11 +238,15 @@ int efi_stub_get_features(uint64_t *ret) { return 0; } -int efi_stub_measured(int log_level) { +int efi_measured_uki(int log_level) { _cleanup_free_ char *pcr_string = NULL; + static int cached = -1; unsigned pcr_nr; int r; + if (cached >= 0) + return cached; + /* Checks if we are booted on a kernel with sd-stub which measured the kernel into PCR 11. Or in * other words, if we are running on a TPM enabled UKI. * @@ -253,16 +257,16 @@ int efi_stub_measured(int log_level) { r = getenv_bool_secure("SYSTEMD_FORCE_MEASURE"); /* Give user a chance to override the variable test, * for debugging purposes */ if (r >= 0) - return r; + return (cached = r); if (r != -ENXIO) log_debug_errno(r, "Failed to parse $SYSTEMD_FORCE_MEASURE, ignoring: %m"); if (!is_efi_boot()) - return 0; + return (cached = 0); r = efi_get_variable_string(EFI_LOADER_VARIABLE(StubPcrKernelImage), &pcr_string); if (r == -ENOENT) - return 0; + return (cached = 0); if (r < 0) return log_full_errno(log_level, r, "Failed to get StubPcrKernelImage EFI variable: %m"); @@ -276,7 +280,7 @@ int efi_stub_measured(int log_level) { "Kernel stub measured kernel image into PCR %u, which is different than expected %i.", pcr_nr, TPM2_PCR_KERNEL_BOOT); - return 1; + return (cached = 1); } int efi_loader_get_config_timeout_one_shot(usec_t *ret) { diff --git a/src/shared/efi-loader.h b/src/shared/efi-loader.h index 834362292a8..c878eea72fc 100644 --- a/src/shared/efi-loader.h +++ b/src/shared/efi-loader.h @@ -18,7 +18,7 @@ int efi_loader_get_entries(char ***ret); int efi_loader_get_features(uint64_t *ret); int efi_stub_get_features(uint64_t *ret); -int efi_stub_measured(int log_level); +int efi_measured_uki(int log_level); int efi_loader_get_config_timeout_one_shot(usec_t *ret); int efi_loader_update_entry_one_shot_cache(char **cache, struct stat *cache_stat); @@ -45,7 +45,7 @@ static inline int efi_stub_get_features(uint64_t *ret) { return -EOPNOTSUPP; } -static inline int efi_stub_measured(int log_level) { +static inline int efi_measured_uki(int log_level) { return log_full_errno(log_level, SYNTHETIC_ERRNO(EOPNOTSUPP), "Compiled without support for EFI"); } diff --git a/units/systemd-pcrfs-root.service.in b/units/systemd-pcrfs-root.service.in index d7941fc1f65..11dc7471946 100644 --- a/units/systemd-pcrfs-root.service.in +++ b/units/systemd-pcrfs-root.service.in @@ -15,8 +15,7 @@ Conflicts=shutdown.target After=systemd-pcrmachine.service Before=shutdown.target ConditionPathExists=!/etc/initrd-release -ConditionSecurity=tpm2 -ConditionPathExists=/sys/firmware/efi/efivars/StubPcrKernelImage-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f +ConditionSecurity=measured-uki [Service] Type=oneshot diff --git a/units/systemd-pcrfs@.service.in b/units/systemd-pcrfs@.service.in index 9ada988f5bd..fbaec4b999e 100644 --- a/units/systemd-pcrfs@.service.in +++ b/units/systemd-pcrfs@.service.in @@ -16,8 +16,7 @@ Conflicts=shutdown.target After=%i.mount systemd-pcrfs-root.service Before=shutdown.target ConditionPathExists=!/etc/initrd-release -ConditionSecurity=tpm2 -ConditionPathExists=/sys/firmware/efi/efivars/StubPcrKernelImage-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f +ConditionSecurity=measured-uki [Service] Type=oneshot diff --git a/units/systemd-pcrmachine.service.in b/units/systemd-pcrmachine.service.in index 9088a66acff..fb7d3ce601f 100644 --- a/units/systemd-pcrmachine.service.in +++ b/units/systemd-pcrmachine.service.in @@ -14,8 +14,7 @@ DefaultDependencies=no Conflicts=shutdown.target Before=sysinit.target shutdown.target ConditionPathExists=!/etc/initrd-release -ConditionSecurity=tpm2 -ConditionPathExists=/sys/firmware/efi/efivars/StubPcrKernelImage-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f +ConditionSecurity=measured-uki [Service] Type=oneshot diff --git a/units/systemd-pcrphase-initrd.service.in b/units/systemd-pcrphase-initrd.service.in index 357c7c58696..b337d602bad 100644 --- a/units/systemd-pcrphase-initrd.service.in +++ b/units/systemd-pcrphase-initrd.service.in @@ -14,8 +14,7 @@ DefaultDependencies=no Conflicts=shutdown.target initrd-switch-root.target Before=sysinit.target cryptsetup-pre.target cryptsetup.target shutdown.target initrd-switch-root.target systemd-sysext.service ConditionPathExists=/etc/initrd-release -ConditionSecurity=tpm2 -ConditionPathExists=/sys/firmware/efi/efivars/StubPcrKernelImage-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f +ConditionSecurity=measured-uki [Service] Type=oneshot diff --git a/units/systemd-pcrphase-sysinit.service.in b/units/systemd-pcrphase-sysinit.service.in index 5ca986fdf73..08f73973bee 100644 --- a/units/systemd-pcrphase-sysinit.service.in +++ b/units/systemd-pcrphase-sysinit.service.in @@ -15,8 +15,7 @@ Conflicts=shutdown.target After=sysinit.target Before=basic.target shutdown.target ConditionPathExists=!/etc/initrd-release -ConditionSecurity=tpm2 -ConditionPathExists=/sys/firmware/efi/efivars/StubPcrKernelImage-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f +ConditionSecurity=measured-uki [Service] Type=oneshot diff --git a/units/systemd-pcrphase.service.in b/units/systemd-pcrphase.service.in index 88d41c2c5d5..c94ad756d40 100644 --- a/units/systemd-pcrphase.service.in +++ b/units/systemd-pcrphase.service.in @@ -13,8 +13,7 @@ Documentation=man:systemd-pcrphase.service(8) After=remote-fs.target remote-cryptsetup.target Before=systemd-user-sessions.service ConditionPathExists=!/etc/initrd-release -ConditionSecurity=tpm2 -ConditionPathExists=/sys/firmware/efi/efivars/StubPcrKernelImage-4a67b082-0a4c-41cf-b6c7-440b29bb8c4f +ConditionSecurity=measured-uki [Service] Type=oneshot