[PATCH 1/3][SRU][E] efi/tpm: Don't access event->count when it isn't mapped.

Seth Forshee seth.forshee at canonical.com
Sat Sep 28 15:46:56 UTC 2019


From: Peter Jones <pjones at redhat.com>

BugLink: https://bugs.launchpad.net/bugs/1845454

Some machines generate a lot of event log entries.  When we're
iterating over them, the code removes the old mapping and adds a
new one, so once we cross the page boundary we're unmapping the page
with the count on it.  Hilarity ensues.

This patch keeps the info from the header in local variables so we don't
need to access that page again or keep track of if it's mapped.

Fixes: 44038bc514a2 ("tpm: Abstract crypto agile event size calculations")
Cc: linux-efi at vger.kernel.org
Cc: linux-integrity at vger.kernel.org
Cc: stable at vger.kernel.org
Signed-off-by: Peter Jones <pjones at redhat.com>
Tested-by: Lyude Paul <lyude at redhat.com>
Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen at linux.intel.com>
Acked-by: Matthew Garrett <mjg59 at google.com>
Acked-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen at linux.intel.com>
Signed-off-by: Ard Biesheuvel <ard.biesheuvel at linaro.org>
(cherry picked from commit 512fb49c9e547f85c588d063cff8bbeb8fd6a643
 git://git.kernel.org/pub/scm/linux/kernel/git/efi/efi.git)
Signed-off-by: Seth Forshee <seth.forshee at canonical.com>
---
 include/linux/tpm_eventlog.h | 14 +++++++++++---
 1 file changed, 11 insertions(+), 3 deletions(-)

diff --git a/include/linux/tpm_eventlog.h b/include/linux/tpm_eventlog.h
index 63238c84dc0b..12584b69a3f3 100644
--- a/include/linux/tpm_eventlog.h
+++ b/include/linux/tpm_eventlog.h
@@ -170,6 +170,7 @@ static inline int __calc_tpm2_event_size(struct tcg_pcr_event2_head *event,
 	u16 halg;
 	int i;
 	int j;
+	u32 count, event_type;
 
 	marker = event;
 	marker_start = marker;
@@ -190,16 +191,22 @@ static inline int __calc_tpm2_event_size(struct tcg_pcr_event2_head *event,
 	}
 
 	event = (struct tcg_pcr_event2_head *)mapping;
+	/*
+	 * the loop below will unmap these fields if the log is larger than
+	 * one page, so save them here for reference.
+	 */
+	count = READ_ONCE(event->count);
+	event_type = READ_ONCE(event->event_type);
 
 	efispecid = (struct tcg_efi_specid_event_head *)event_header->event;
 
 	/* Check if event is malformed. */
-	if (event->count > efispecid->num_algs) {
+	if (count > efispecid->num_algs) {
 		size = 0;
 		goto out;
 	}
 
-	for (i = 0; i < event->count; i++) {
+	for (i = 0; i < count; i++) {
 		halg_size = sizeof(event->digests[i].alg_id);
 
 		/* Map the digest's algorithm identifier */
@@ -256,8 +263,9 @@ static inline int __calc_tpm2_event_size(struct tcg_pcr_event2_head *event,
 		+ event_field->event_size;
 	size = marker - marker_start;
 
-	if ((event->event_type == 0) && (event_field->event_size == 0))
+	if (event_type == 0 && event_field->event_size == 0)
 		size = 0;
+
 out:
 	if (do_mapping)
 		TPM_MEMUNMAP(mapping, mapping_size);
-- 
2.20.1




More information about the kernel-team mailing list