Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
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 887f98f (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 30708df)
  • Loading branch information
WenhuaChang authored and frozencemetery committed Mar 30, 2023
1 parent 2becfab commit b09440d
Show file tree
Hide file tree
Showing 4 changed files with 58 additions and 10 deletions.
37 changes: 37 additions & 0 deletions grub-core/commands/efi/tpm.c
Expand Up @@ -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);
}
}
20 changes: 10 additions & 10 deletions grub-core/commands/ieee1275/ibmvtpm.c
Expand Up @@ -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);

Expand All @@ -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;
}
10 changes: 10 additions & 0 deletions grub-core/commands/tpm.c
Expand Up @@ -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);
}
1 change: 1 addition & 0 deletions include/grub/tpm.h
Expand Up @@ -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

0 comments on commit b09440d

Please sign in to comment.