pcrphase: gracefully exit if TPM2 support is incomplete

If everything points to the fact that TPM2 should work, but then the
driver fails to initialize we should handle this gracefully and not
cause failing services all over the place.

Fixes: #25700
This commit is contained in:
Lennart Poettering 2022-12-15 18:07:20 +01:00
parent ad48ff12bd
commit 0318d54539
5 changed files with 27 additions and 6 deletions

View file

@ -131,6 +131,14 @@
all suitable TPM2 devices currently discovered.</para></listitem>
</varlistentry>
<varlistentry>
<term><option>--graceful</option></term>
<listitem><para>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.</para></listitem>
</varlistentry>
<xi:include href="standard-options.xml" xpointer="help" />
<xi:include href="standard-options.xml" xpointer="version" />

View file

@ -14,6 +14,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;
@ -35,6 +36,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,
@ -51,6 +53,7 @@ static int parse_argv(int argc, char *argv[]) {
ARG_VERSION = 0x100,
ARG_BANK,
ARG_TPM2_DEVICE,
ARG_GRACEFUL,
};
static const struct option options[] = {
@ -58,6 +61,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 },
{}
};
@ -105,6 +109,10 @@ static int parse_argv(int argc, char *argv[]) {
break;
}
case ARG_GRACEFUL:
arg_graceful = true;
break;
case '?':
return -EINVAL;
@ -174,6 +182,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);
int b = getenv_bool("SYSTEMD_PCRPHASE_STUB_VERIFY");

View file

@ -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

View file

@ -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

View file

@ -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