From: Ana Bobillo <[email protected]>
With TCG2 measured boot, efi_load_pe() measures each image into PCR 4
or 2, but it gives up only when the measurement reports that no TPM was
found. Any other error is ignored, so an image whose hash cannot be
computed, because efi_image_parse() rejects it, or whose PCR could not
be extended is loaded and can be started without being measured. With
the range checks added to efi_image_parse() earlier in this series,
more malformed images take this path.
As EDK2's DxeTpm2MeasureBootLib does, refuse to load an image whose
measurement failed: free the memory allocated for it, which the error
path leaked so far, and return EFI_ACCESS_DENIED, so that LoadImage()
returns no image handle. A full event log is no error, as there: the
PCR is extended all the same.
Fixes: 163a0d7e2cbd ("efi_loader: add PE/COFF image measurement")
Signed-off-by: Ana Bobillo <[email protected]>
---
lib/efi_loader/efi_image_loader.c | 22 ++++++++++++++++------
1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/lib/efi_loader/efi_image_loader.c
b/lib/efi_loader/efi_image_loader.c
index c4f64f102e8..c33b693c4ff 100644
--- a/lib/efi_loader/efi_image_loader.c
+++ b/lib/efi_loader/efi_image_loader.c
@@ -1166,12 +1166,22 @@ efi_status_t efi_load_pe(struct efi_loaded_image_obj
*handle,
#if IS_ENABLED(CONFIG_EFI_TCG2_PROTOCOL)
/* Measure an PE/COFF image */
ret = tcg2_measure_pe_image(efi, efi_size, handle, loaded_image_info);
- if (ret == EFI_SECURITY_VIOLATION) {
- /*
- * TCG2 Protocol is installed but no TPM device found,
- * this is not expected.
- */
- log_err("PE image measurement failed, no tpm device found\n");
+ /*
+ * Do not load an image that could not be measured. A full event log
+ * is no error: the PCR has been extended all the same.
+ */
+ if (ret != EFI_SUCCESS && ret != EFI_VOLUME_FULL) {
+ if (ret == EFI_SECURITY_VIOLATION)
+ /*
+ * TCG2 Protocol is installed but no TPM device found,
+ * this is not expected.
+ */
+ log_err("PE image measurement failed, no tpm device
found\n");
+ else
+ log_err("PE image measurement failed\n");
+ efi_free_pages((uintptr_t)efi_reloc,
+ (virt_size + EFI_PAGE_MASK) >> EFI_PAGE_SHIFT);
+ ret = EFI_ACCESS_DENIED;
goto err;
}