security/tpm: Respect CBMEM TPM log size

The preram TPM log was being copied to the end of the CBMEM TPM log no
matter what the size of the CBMEM TPM log was. Eventually, it would
overwrite anything else in CBMEM beyond the TPM log.

This can currently be reproduced by enabling TPM_MEASURED_BOOT and
performing multiple S3 suspends, as coreboot is incorrectly performing
TPM measurements on S3 resume.

Change-Id: If76299e68eb5ed2ed20c947be35cea46c51fcdec
Signed-off-by: Jeremy Soller <jeremy@system76.com>
Signed-off-by: Tim Crawford <tcrawford@system76.com>
Reviewed-on: https://review.coreboot.org/c/coreboot/+/73297
Reviewed-by: Martin L Roth <gaumless@gmail.com>
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
diff --git a/src/security/tpm/tspi/log-tpm1.c b/src/security/tpm/tspi/log-tpm1.c
index 5294426..3b192d7 100644
--- a/src/security/tpm/tspi/log-tpm1.c
+++ b/src/security/tpm/tspi/log-tpm1.c
@@ -170,6 +170,11 @@
 	int i;
 
 	for (i = 0; i < le16toh(from_log->vendor.num_entries); i++) {
+		if (le16toh(to_log->vendor.num_entries) >= le16toh(to_log->vendor.max_entries)) {
+			printk(BIOS_WARNING, "TPM LOG: log table is full\n");
+			return;
+		}
+
 		struct tpm_1_log_entry *tce =
 			&to_log->entries[le16toh(to_log->vendor.num_entries)];
 		memcpy(tce, &from_log->entries[i], sizeof(*tce));
diff --git a/src/security/tpm/tspi/log-tpm2.c b/src/security/tpm/tspi/log-tpm2.c
index 897cced..c7bbc9e 100644
--- a/src/security/tpm/tspi/log-tpm2.c
+++ b/src/security/tpm/tspi/log-tpm2.c
@@ -213,6 +213,11 @@
 	int i;
 
 	for (i = 0; i < le16toh(from_log->vendor.num_entries); i++) {
+		if (le16toh(to_log->vendor.num_entries) >= le16toh(to_log->vendor.max_entries)) {
+			printk(BIOS_WARNING, "TPM LOG: log table is full\n");
+			return;
+		}
+
 		struct tpm_2_log_entry *tce =
 			&to_log->entries[le16toh(to_log->vendor.num_entries)];
 		to_log->vendor.num_entries = htole16(le16toh(to_log->vendor.num_entries) + 1);
diff --git a/src/security/tpm/tspi/log.c b/src/security/tpm/tspi/log.c
index b7e59f8..9798eab 100644
--- a/src/security/tpm/tspi/log.c
+++ b/src/security/tpm/tspi/log.c
@@ -145,6 +145,11 @@
 	int i;
 
 	for (i = 0; i < from_log->num_entries; i++) {
+		if (to_log->num_entries >= to_log->max_entries) {
+			printk(BIOS_ERR, "TPM LOG: log table is full\n");
+			return;
+		}
+
 		struct tpm_cb_log_entry *tce = &to_log->entries[to_log->num_entries++];
 
 		strncpy(tce->name, from_log->entries[i].name, TPM_CB_LOG_PCR_HASH_NAME - 1);