You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
157 lines
5.4 KiB
157 lines
5.4 KiB
1 month ago
|
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||
|
From: Michael Chang <mchang@suse.com>
|
||
|
Date: Wed, 22 Mar 2023 12:25:43 +0800
|
||
|
Subject: [PATCH] tpm: Disable the tpm verifier if the TPM device is not
|
||
|
present
|
||
|
|
||
|
When the tpm module is loaded, the verifier reads entire file into
|
||
|
memory, measures it and uses verified content as a backing buffer for
|
||
|
file accesses. However, this process may result in high memory
|
||
|
utilization for file operations, sometimes causing a system to run out
|
||
|
of memory which may finally lead to boot failure. To address this issue,
|
||
|
among others, the commit 887f98f0d (mm: Allow dynamically requesting
|
||
|
additional memory regions) have optimized memory management by
|
||
|
dynamically allocating heap space to maximize memory usage and reduce
|
||
|
threat of memory exhaustion. But in some cases problems may still arise,
|
||
|
e.g., when large ISO images are mounted using loopback or when dealing
|
||
|
with embedded systems with limited memory resources.
|
||
|
|
||
|
Unfortunately current implementation of the tpm module doesn't allow
|
||
|
elimination of the back buffer once it is loaded. Even if the TPM device
|
||
|
is not present or it has been explicitly disabled. This may unnecessary
|
||
|
allocate a lot memory. To solve this issue, a patch has been developed
|
||
|
to detect the TPM status at module load and skip verifier registration
|
||
|
if the device is missing or deactivated. This prevents allocation of
|
||
|
memory for the back buffer, avoiding wasting memory when no real measure
|
||
|
boot functionality is performed. Disabling the TPM device in the system
|
||
|
can reduce memory usage in the GRUB. It is useful in scenarios where
|
||
|
high memory utilization is a concern and measurements of loaded
|
||
|
artifacts are not necessary.
|
||
|
|
||
|
Signed-off-by: Michael Chang <mchang@suse.com>
|
||
|
Signed-off-by: Stefan Berger <stefanb@linux.ibm.com>
|
||
|
Reviewed-by: Daniel Kiper <daniel.kiper@oracle.com>
|
||
|
(cherry picked from commit 30708dfe3bebd62a5487437554da8a24253f519f)
|
||
|
---
|
||
|
grub-core/commands/efi/tpm.c | 37 +++++++++++++++++++++++++++++++++++
|
||
|
grub-core/commands/ieee1275/ibmvtpm.c | 20 +++++++++----------
|
||
|
grub-core/commands/tpm.c | 10 ++++++++++
|
||
|
include/grub/tpm.h | 1 +
|
||
|
4 files changed, 58 insertions(+), 10 deletions(-)
|
||
|
|
||
|
diff --git a/grub-core/commands/efi/tpm.c b/grub-core/commands/efi/tpm.c
|
||
|
index ae09c1bf8b..e1f343fea3 100644
|
||
|
--- a/grub-core/commands/efi/tpm.c
|
||
|
+++ b/grub-core/commands/efi/tpm.c
|
||
|
@@ -287,3 +287,40 @@ grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
|
||
|
else
|
||
|
return grub_tpm2_log_event (tpm_handle, buf, size, pcr, description);
|
||
|
}
|
||
|
+
|
||
|
+int
|
||
|
+grub_tpm_present (void)
|
||
|
+{
|
||
|
+ grub_efi_handle_t tpm_handle;
|
||
|
+ grub_efi_uint8_t protocol_version;
|
||
|
+
|
||
|
+ if (!grub_tpm_handle_find (&tpm_handle, &protocol_version))
|
||
|
+ return 0;
|
||
|
+
|
||
|
+ if (protocol_version == 1)
|
||
|
+ {
|
||
|
+ grub_efi_tpm_protocol_t *tpm;
|
||
|
+
|
||
|
+ tpm = grub_efi_open_protocol (tpm_handle, &tpm_guid,
|
||
|
+ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||
|
+ if (!tpm)
|
||
|
+ {
|
||
|
+ grub_dprintf ("tpm", "Cannot open TPM protocol\n");
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+ return grub_tpm1_present (tpm);
|
||
|
+ }
|
||
|
+ else
|
||
|
+ {
|
||
|
+ grub_efi_tpm2_protocol_t *tpm;
|
||
|
+
|
||
|
+ tpm = grub_efi_open_protocol (tpm_handle, &tpm2_guid,
|
||
|
+ GRUB_EFI_OPEN_PROTOCOL_GET_PROTOCOL);
|
||
|
+ if (!tpm)
|
||
|
+ {
|
||
|
+ grub_dprintf ("tpm", "Cannot open TPM protocol\n");
|
||
|
+ return 0;
|
||
|
+ }
|
||
|
+ return grub_tpm2_present (tpm);
|
||
|
+ }
|
||
|
+}
|
||
|
diff --git a/grub-core/commands/ieee1275/ibmvtpm.c b/grub-core/commands/ieee1275/ibmvtpm.c
|
||
|
index 239942d27e..a6fee5c516 100644
|
||
|
--- a/grub-core/commands/ieee1275/ibmvtpm.c
|
||
|
+++ b/grub-core/commands/ieee1275/ibmvtpm.c
|
||
|
@@ -135,16 +135,6 @@ grub_err_t
|
||
|
grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
|
||
|
const char *description)
|
||
|
{
|
||
|
- /*
|
||
|
- * Call tpm_init() 'late' rather than from GRUB_MOD_INIT() so that device nodes
|
||
|
- * can be found.
|
||
|
- */
|
||
|
- grub_err_t err = tpm_init ();
|
||
|
-
|
||
|
- /* Absence of a TPM isn't a failure. */
|
||
|
- if (err != GRUB_ERR_NONE)
|
||
|
- return GRUB_ERR_NONE;
|
||
|
-
|
||
|
grub_dprintf ("tpm", "log_event, pcr = %d, size = 0x%" PRIxGRUB_SIZE ", %s\n",
|
||
|
pcr, size, description);
|
||
|
|
||
|
@@ -153,3 +143,13 @@ grub_tpm_measure (unsigned char *buf, grub_size_t size, grub_uint8_t pcr,
|
||
|
|
||
|
return GRUB_ERR_NONE;
|
||
|
}
|
||
|
+
|
||
|
+int
|
||
|
+grub_tpm_present (void)
|
||
|
+{
|
||
|
+ /*
|
||
|
+ * Call tpm_init() "late" rather than from GRUB_MOD_INIT() so that device nodes
|
||
|
+ * can be found.
|
||
|
+ */
|
||
|
+ return tpm_init() == GRUB_ERR_NONE;
|
||
|
+}
|
||
|
diff --git a/grub-core/commands/tpm.c b/grub-core/commands/tpm.c
|
||
|
index e287d042e6..5839053d3d 100644
|
||
|
--- a/grub-core/commands/tpm.c
|
||
|
+++ b/grub-core/commands/tpm.c
|
||
|
@@ -86,10 +86,20 @@ struct grub_file_verifier grub_tpm_verifier = {
|
||
|
|
||
|
GRUB_MOD_INIT (tpm)
|
||
|
{
|
||
|
+ /*
|
||
|
+ * Even though this now calls ibmvtpm's grub_tpm_present() from GRUB_MOD_INIT(),
|
||
|
+ * it does seem to call it late enough in the initialization sequence so
|
||
|
+ * that whatever discovered "device nodes" before this GRUB_MOD_INIT() is
|
||
|
+ * called, enables the ibmvtpm driver to see the device nodes.
|
||
|
+ */
|
||
|
+ if (!grub_tpm_present())
|
||
|
+ return;
|
||
|
grub_verifier_register (&grub_tpm_verifier);
|
||
|
}
|
||
|
|
||
|
GRUB_MOD_FINI (tpm)
|
||
|
{
|
||
|
+ if (!grub_tpm_present())
|
||
|
+ return;
|
||
|
grub_verifier_unregister (&grub_tpm_verifier);
|
||
|
}
|
||
|
diff --git a/include/grub/tpm.h b/include/grub/tpm.h
|
||
|
index 5c285cbc52..c19fcbd0a6 100644
|
||
|
--- a/include/grub/tpm.h
|
||
|
+++ b/include/grub/tpm.h
|
||
|
@@ -36,4 +36,5 @@
|
||
|
|
||
|
grub_err_t grub_tpm_measure (unsigned char *buf, grub_size_t size,
|
||
|
grub_uint8_t pcr, const char *description);
|
||
|
+int grub_tpm_present (void);
|
||
|
#endif
|