summaryrefslogtreecommitdiff
path: root/drivers/char/tpm
diff options
context:
space:
mode:
authorPetr Vandrovec <petr@vmware.com>2017-03-29 00:43:30 -0700
committerJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>2017-04-25 00:27:18 +0300
commitfd5c78694f3f1c875e293de7a641ba8a3d60d00d (patch)
treefcff3dc9a930e3e36f631d97d83a0c009332328b /drivers/char/tpm
parent3b395d67d9d6c20d142f6a1618c44577d3d79347 (diff)
tpm: fix handling of the TPM 2.0 event logs
When TPM2 log has entries with more than 3 digests, or with digests not listed in the log header, log gets misparsed, eventually leading to kernel complaint that code tried to vmalloc 512MB of memory (I have no idea what would happen on bigger system). So code should not parse only first 3 digests: both event header and event itself are already in memory, so we can parse any number of digests, as long as we do not try to parse whole memory when given count of 0xFFFFFFFF. So this change: * Rejects event entry with more digests than log header describes. Digest types should be unique, and all should be described in log header, so there cannot be more digests in the event than in the header. * Reject event entry with digest that is not described in the log header. In theory code could hardcode information about digest IDs already assigned by TCG, but if firmware authors cannot get event log format right, why should anyone believe that they got event log content right. Cc: stable@vger.kernel.org Fixes: 4d23cc323cdb ("tpm: add securityfs support for TPM 2.0 firmware event log") Signed-off-by: Petr Vandrovec <petr@vmware.com> Reviewed-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Diffstat (limited to 'drivers/char/tpm')
-rw-r--r--drivers/char/tpm/tpm2_eventlog.c14
1 files changed, 10 insertions, 4 deletions
diff --git a/drivers/char/tpm/tpm2_eventlog.c b/drivers/char/tpm/tpm2_eventlog.c
index 513897cf9c4b..34a8afa69138 100644
--- a/drivers/char/tpm/tpm2_eventlog.c
+++ b/drivers/char/tpm/tpm2_eventlog.c
@@ -56,18 +56,24 @@ static int calc_tpm2_event_size(struct tcg_pcr_event2 *event,
efispecid = (struct tcg_efi_specid_event *)event_header->event;
- for (i = 0; (i < event->count) && (i < TPM2_ACTIVE_PCR_BANKS);
- i++) {
+ /* Check if event is malformed. */
+ if (event->count > efispecid->num_algs)
+ return 0;
+
+ for (i = 0; i < event->count; i++) {
halg_size = sizeof(event->digests[i].alg_id);
memcpy(&halg, marker, halg_size);
marker = marker + halg_size;
- for (j = 0; (j < efispecid->num_algs); j++) {
+ for (j = 0; j < efispecid->num_algs; j++) {
if (halg == efispecid->digest_sizes[j].alg_id) {
- marker = marker +
+ marker +=
efispecid->digest_sizes[j].digest_size;
break;
}
}
+ /* Algorithm without known length. Such event is unparseable. */
+ if (j == efispecid->num_algs)
+ return 0;
}
event_field = (struct tcg_event_field *)marker;