diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/boot/pcrphase.c | 38 | ||||
-rw-r--r-- | src/cryptsetup/cryptsetup.c | 9 | ||||
-rw-r--r-- | src/fstab-generator/fstab-generator.c | 12 | ||||
-rw-r--r-- | src/gpt-auto-generator/gpt-auto-generator.c | 10 | ||||
-rw-r--r-- | src/shared/efi-loader.c | 39 | ||||
-rw-r--r-- | src/shared/efi-loader.h | 2 |
6 files changed, 74 insertions, 36 deletions
diff --git a/src/boot/pcrphase.c b/src/boot/pcrphase.c index 70c919b0f5..003e0b8ad8 100644 --- a/src/boot/pcrphase.c +++ b/src/boot/pcrphase.c @@ -9,15 +9,14 @@ #include "blockdev-util.h" #include "build.h" #include "chase-symlinks.h" +#include "efi-loader.h" #include "efivars.h" -#include "env-util.h" #include "escape.h" #include "fd-util.h" #include "main-func.h" #include "mountpoint-util.h" #include "openssl-util.h" #include "parse-argument.h" -#include "parse-util.h" #include "pretty-print.h" #include "tpm-pcr.h" #include "tpm2-util.h" @@ -241,9 +240,9 @@ static int get_file_system_word( } static int run(int argc, char *argv[]) { - _cleanup_free_ char *joined = NULL, *pcr_string = NULL, *word = NULL; _cleanup_(tpm2_context_destroy) struct tpm2_context c = {}; - unsigned target_pcr_nr, efi_pcr_nr; + _cleanup_free_ char *joined = NULL, *word = NULL; + unsigned target_pcr_nr; size_t length; int r; @@ -334,32 +333,13 @@ static int run(int argc, char *argv[]) { length = strlen(word); - int b = getenv_bool("SYSTEMD_PCRPHASE_STUB_VERIFY"); - if (b < 0 && b != -ENXIO) - log_warning_errno(b, "Unable to parse $SYSTEMD_PCRPHASE_STUB_VERIFY value, ignoring."); - /* Skip logic if sd-stub is not used, after all PCR 11 might have a very different purpose then. */ - r = efi_get_variable_string(EFI_LOADER_VARIABLE(StubPcrKernelImage), &pcr_string); - if (r == -ENOENT) { - if (b != 0) { - log_info("Kernel stub did not measure kernel image into PCR %u, skipping measurement.", TPM_PCR_INDEX_KERNEL_IMAGE); - return EXIT_SUCCESS; - } else - log_notice("Kernel stub did not measure kernel image into PCR %u, but told to measure anyway, hence proceeding.", TPM_PCR_INDEX_KERNEL_IMAGE); - } else if (r < 0) - return log_error_errno(r, "Failed to read StubPcrKernelImage EFI variable: %m"); - else { - /* Let's validate that the stub announced PCR 11 as we expected. */ - r = safe_atou(pcr_string, &efi_pcr_nr); - if (r < 0) - return log_error_errno(r, "Failed to parse StubPcrKernelImage EFI variable: %s", pcr_string); - if (efi_pcr_nr != TPM_PCR_INDEX_KERNEL_IMAGE) { - if (b != 0) - return log_error_errno(SYNTHETIC_ERRNO(EREMOTE), "Kernel stub measured kernel image into PCR %u, which is different than expected %u.", efi_pcr_nr, TPM_PCR_INDEX_KERNEL_IMAGE); - else - log_notice("Kernel stub measured kernel image into PCR %u, which is different than expected %u, but told to measure anyway, hence proceeding.", efi_pcr_nr, TPM_PCR_INDEX_KERNEL_IMAGE); - } else - log_debug("Kernel stub reported same PCR %u as we want to use, proceeding.", TPM_PCR_INDEX_KERNEL_IMAGE); + r = efi_stub_measured(); + if (r < 0) + return log_error_errno(r, "Failed to detect if we are running on a kernel image with TPM measurement enabled: %m"); + if (r == 0) { + log_info("Kernel stub did not measure kernel image into PCR %u, skipping userspace measurement, too.", TPM_PCR_INDEX_KERNEL_IMAGE); + return EXIT_SUCCESS; } r = dlopen_tpm2(); diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c index 5efce63a38..2c9d416734 100644 --- a/src/cryptsetup/cryptsetup.c +++ b/src/cryptsetup/cryptsetup.c @@ -19,6 +19,7 @@ #include "cryptsetup-util.h" #include "device-util.h" #include "efi-api.h" +#include "efi-loader.h" #include "env-util.h" #include "escape.h" #include "fileio.h" @@ -827,6 +828,14 @@ static int measure_volume_key( return 0; } + r = efi_stub_measured(); + if (r < 0) + return log_warning_errno(r, "Failed to detect if we are running on a kernel image with TPM measurement enabled: %m"); + if (r == 0) { + log_debug("Kernel stub did not measure kernel image into the expected PCR, skipping userspace measurement, too."); + return 0; + } + #if HAVE_TPM2 r = dlopen_tpm2(); if (r < 0) diff --git a/src/fstab-generator/fstab-generator.c b/src/fstab-generator/fstab-generator.c index 4b763bc247..ed34e0a32f 100644 --- a/src/fstab-generator/fstab-generator.c +++ b/src/fstab-generator/fstab-generator.c @@ -8,6 +8,7 @@ #include "bus-error.h" #include "bus-locator.h" #include "chase-symlinks.h" +#include "efi-loader.h" #include "fd-util.h" #include "fileio.h" #include "fstab-util.h" @@ -529,9 +530,16 @@ static int add_mount( } if (flags & MOUNT_PCRFS) { - r = generator_hook_up_pcrfs(dest, where, target_unit); + r = efi_stub_measured(); if (r < 0) - return r; + log_warning_errno(r, "Failed to detect if we are running on a kernel image with TPM measurement enabled, assuming not: %m"); + else if (r == 0) + log_debug("Kernel stub did not measure kernel image into PCR, skipping userspace measurement, too."); + else { + r = generator_hook_up_pcrfs(dest, where, target_unit); + if (r < 0) + return r; + } } if (!FLAGS_SET(flags, MOUNT_AUTOMOUNT)) { diff --git a/src/gpt-auto-generator/gpt-auto-generator.c b/src/gpt-auto-generator/gpt-auto-generator.c index 63bb2a3cbb..9b11318017 100644 --- a/src/gpt-auto-generator/gpt-auto-generator.c +++ b/src/gpt-auto-generator/gpt-auto-generator.c @@ -102,11 +102,11 @@ 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_get_variable(EFI_LOADER_VARIABLE(StubPcrKernelImage), NULL, NULL, NULL); /* we don't actually care which PCR the UKI used for itself */ - if (r == -ENOENT) - log_debug_errno(r, "Will not measure volume key of volume '%s', because not booted via systemd-stub with measurements enabled.", id); - else if (r < 0) - log_debug_errno(r, "Failed to determine whether booted via systemd-stub with measurements enabled, ignoring: %m"); + r = efi_stub_measured(); + if (r < 0) + log_warning_errno(r, "Failed to determine whether booted via systemd-stub with measurements enabled, ignoring: %m"); + else if (r == 0) + log_debug("Will not measure volume key of volume '%s', because not booted via systemd-stub with measurements enabled.", id); else if (!strextend_with_separator(&options, ",", "tpm2-measure-pcr=yes")) return log_oom(); } diff --git a/src/shared/efi-loader.c b/src/shared/efi-loader.c index 1340412cda..621fa082ba 100644 --- a/src/shared/efi-loader.c +++ b/src/shared/efi-loader.c @@ -2,10 +2,12 @@ #include "alloc-util.h" #include "efi-loader.h" +#include "env-util.h" #include "parse-util.h" #include "path-util.h" #include "stat-util.h" #include "strv.h" +#include "tpm-pcr.h" #include "utf8.h" #if ENABLE_EFI @@ -236,6 +238,43 @@ int efi_stub_get_features(uint64_t *ret) { return 0; } +int efi_stub_measured(void) { + _cleanup_free_ char *pcr_string = NULL; + unsigned pcr_nr; + int r; + + /* 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. + * + * Returns == 0 and > 0 depending on the result of the test. Returns -EREMOTE if we detected a stub + * being used, but it measured things into a different PCR than we are configured for in + * userspace. (i.e. we expect PCR 11 being used for this by both sd-stub and us) */ + + r = getenv_bool_secure("SYSTEMD_FORCE_MEASURE"); /* Give user a chance to override the variable test, + * for debugging purposes */ + if (r >= 0) + return r; + if (r != -ENXIO) + log_debug_errno(r, "Failed to parse $SYSTEMD_FORCE_MEASURE, ignoring: %m"); + + if (!is_efi_boot()) + return 0; + + r = efi_get_variable_string(EFI_LOADER_VARIABLE(StubPcrKernelImage), &pcr_string); + if (r == -ENOENT) + return 0; + if (r < 0) + return r; + + r = safe_atou(pcr_string, &pcr_nr); + if (r < 0) + return log_debug_errno(r, "Failed to parse StubPcrKernelImage EFI variable: %s", pcr_string); + if (pcr_nr != TPM_PCR_INDEX_KERNEL_IMAGE) + return log_debug_errno(SYNTHETIC_ERRNO(EREMOTE), "Kernel stub measured kernel image into PCR %u, which is different than expected %u.", pcr_nr, TPM_PCR_INDEX_KERNEL_IMAGE); + + return 1; +} + int efi_loader_get_config_timeout_one_shot(usec_t *ret) { _cleanup_free_ char *v = NULL; static struct stat cache_stat = {}; diff --git a/src/shared/efi-loader.h b/src/shared/efi-loader.h index 84968869ab..56ccdee9c1 100644 --- a/src/shared/efi-loader.h +++ b/src/shared/efi-loader.h @@ -18,6 +18,8 @@ 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(void); + 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); |