diff --git a/man/systemd-pcrphase.service.xml b/man/systemd-pcrphase.service.xml index 9eda503e4c..9b7cc80b3a 100644 --- a/man/systemd-pcrphase.service.xml +++ b/man/systemd-pcrphase.service.xml @@ -131,6 +131,14 @@ all suitable TPM2 devices currently discovered. + + + + If no TPM2 firmware, kernel subsystem, kernel driver or device support is found, exit + with exit status 0 (i.e. indicate success). If this is not specified any attempt to measure without a + TPM2 device will cause the invocation to fail. + + diff --git a/src/boot/pcrphase.c b/src/boot/pcrphase.c index 267f66767c..e5d33ff1a2 100644 --- a/src/boot/pcrphase.c +++ b/src/boot/pcrphase.c @@ -12,6 +12,7 @@ #include "tpm-pcr.h" #include "tpm2-util.h" +static bool arg_graceful = false; static char *arg_tpm2_device = NULL; static char **arg_banks = NULL; @@ -33,6 +34,7 @@ static int help(int argc, char *argv[], void *userdata) { " --version Print version\n" " --bank=DIGEST Select TPM bank (SHA1, SHA256)\n" " --tpm2-device=PATH Use specified TPM2 device\n" + " --graceful Exit gracefully if no TPM2 device is found\n" "\nSee the %2$s for details.\n", program_invocation_short_name, link, @@ -49,6 +51,7 @@ static int parse_argv(int argc, char *argv[]) { ARG_VERSION = 0x100, ARG_BANK, ARG_TPM2_DEVICE, + ARG_GRACEFUL, }; static const struct option options[] = { @@ -56,6 +59,7 @@ static int parse_argv(int argc, char *argv[]) { { "version", no_argument, NULL, ARG_VERSION }, { "bank", required_argument, NULL, ARG_BANK }, { "tpm2-device", required_argument, NULL, ARG_TPM2_DEVICE }, + { "graceful", no_argument, NULL, ARG_GRACEFUL }, {} }; @@ -103,6 +107,10 @@ static int parse_argv(int argc, char *argv[]) { break; } + case ARG_GRACEFUL: + arg_graceful = true; + break; + case '?': return -EINVAL; @@ -172,6 +180,11 @@ static int run(int argc, char *argv[]) { if (isempty(word)) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "String to measure cannot be empty, refusing."); + if (arg_graceful && tpm2_support() != TPM2_SUPPORT_FULL) { + log_notice("No complete TPM2 support detected, exiting gracefully."); + return EXIT_SUCCESS; + } + length = strlen(word); /* Skip logic if sd-stub is not used, after all PCR 11 might have a very different purpose then. */ diff --git a/units/systemd-pcrphase-initrd.service.in b/units/systemd-pcrphase-initrd.service.in index c1ad5ef844..e437c7e1ce 100644 --- a/units/systemd-pcrphase-initrd.service.in +++ b/units/systemd-pcrphase-initrd.service.in @@ -20,5 +20,5 @@ ConditionPathExists=/sys/firmware/efi/efivars/StubPcrKernelImage-4a67b082-0a4c-4 [Service] Type=oneshot RemainAfterExit=yes -ExecStart={{ROOTLIBEXECDIR}}/systemd-pcrphase enter-initrd -ExecStop={{ROOTLIBEXECDIR}}/systemd-pcrphase leave-initrd +ExecStart={{ROOTLIBEXECDIR}}/systemd-pcrphase --graceful enter-initrd +ExecStop={{ROOTLIBEXECDIR}}/systemd-pcrphase --graceful leave-initrd diff --git a/units/systemd-pcrphase-sysinit.service.in b/units/systemd-pcrphase-sysinit.service.in index 6b5ba7d878..a22fbbe935 100644 --- a/units/systemd-pcrphase-sysinit.service.in +++ b/units/systemd-pcrphase-sysinit.service.in @@ -21,5 +21,5 @@ ConditionPathExists=/sys/firmware/efi/efivars/StubPcrKernelImage-4a67b082-0a4c-4 [Service] Type=oneshot RemainAfterExit=yes -ExecStart={{ROOTLIBEXECDIR}}/systemd-pcrphase sysinit -ExecStop={{ROOTLIBEXECDIR}}/systemd-pcrphase final +ExecStart={{ROOTLIBEXECDIR}}/systemd-pcrphase --graceful sysinit +ExecStop={{ROOTLIBEXECDIR}}/systemd-pcrphase --graceful final diff --git a/units/systemd-pcrphase.service.in b/units/systemd-pcrphase.service.in index ce469befa8..5ba437e5b1 100644 --- a/units/systemd-pcrphase.service.in +++ b/units/systemd-pcrphase.service.in @@ -19,5 +19,5 @@ ConditionPathExists=/sys/firmware/efi/efivars/StubPcrKernelImage-4a67b082-0a4c-4 [Service] Type=oneshot RemainAfterExit=yes -ExecStart={{ROOTLIBEXECDIR}}/systemd-pcrphase ready -ExecStop={{ROOTLIBEXECDIR}}/systemd-pcrphase shutdown +ExecStart={{ROOTLIBEXECDIR}}/systemd-pcrphase --graceful ready +ExecStop={{ROOTLIBEXECDIR}}/systemd-pcrphase --graceful shutdown