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