[PATCH 2/5] tpm: Fix event log types for TPM2

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



From: Matthew Garrett <mjg59@xxxxxxxxxx>

These structs are defined as having variable length members, not fixed
size ones. Fix that up and rename them to more accurately describe the
only safe way they can be used, and fix the code that relied on having
fixed structures.

Signed-off-by: Matthew Garrett <mjg59@xxxxxxxxxx>
---
 drivers/char/tpm/eventlog/tpm2.c |  8 ++++----
 drivers/char/tpm/tpm-interface.c | 32 ++++++++++++++++++++++++--------
 drivers/char/tpm/tpm.h           |  3 ++-
 drivers/char/tpm/tpm2-cmd.c      | 15 ++++++++++++++-
 include/linux/tpm_eventlog.h     | 27 +++++++++++++++++++++------
 5 files changed, 65 insertions(+), 20 deletions(-)

diff --git a/drivers/char/tpm/eventlog/tpm2.c b/drivers/char/tpm/eventlog/tpm2.c
index 5023f7f284ef..1343179c0a0e 100644
--- a/drivers/char/tpm/eventlog/tpm2.c
+++ b/drivers/char/tpm/eventlog/tpm2.c
@@ -37,7 +37,7 @@
  *
  * Returns size of the event. If it is an invalid event, returns 0.
  */
-static int calc_tpm2_event_size(struct tcg_pcr_event2 *event,
+static int calc_tpm2_event_size(struct tcg_pcr_event2_hdr *event,
 				struct tcg_pcr_event *event_header)
 {
 	return _calc_tpm2_event_size(event, event_header);
@@ -50,7 +50,7 @@ static void *tpm2_bios_measurements_start(struct seq_file *m, loff_t *pos)
 	void *addr = log->bios_event_log;
 	void *limit = log->bios_event_log_end;
 	struct tcg_pcr_event *event_header;
-	struct tcg_pcr_event2 *event;
+	struct tcg_pcr_event2_hdr *event;
 	size_t size;
 	int i;
 
@@ -91,7 +91,7 @@ static void *tpm2_bios_measurements_next(struct seq_file *m, void *v,
 					 loff_t *pos)
 {
 	struct tcg_pcr_event *event_header;
-	struct tcg_pcr_event2 *event;
+	struct tcg_pcr_event2_hdr *event;
 	struct tpm_chip *chip = m->private;
 	struct tpm_bios_log *log = &chip->log;
 	void *limit = log->bios_event_log_end;
@@ -135,7 +135,7 @@ static int tpm2_binary_bios_measurements_show(struct seq_file *m, void *v)
 	struct tpm_chip *chip = m->private;
 	struct tpm_bios_log *log = &chip->log;
 	struct tcg_pcr_event *event_header = log->bios_event_log;
-	struct tcg_pcr_event2 *event = v;
+	struct tcg_pcr_event2_hdr *event = v;
 	void *temp_ptr;
 	size_t size;
 
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index d9439f9abe78..33abe5406d38 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -488,21 +488,37 @@ EXPORT_SYMBOL_GPL(tpm_pcr_read);
 int tpm_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, const u8 *hash)
 {
 	int rc;
-	struct tpm2_digest digest_list[ARRAY_SIZE(chip->active_banks)];
 	u32 count = 0;
-	int i;
+	int i, size = 0;
+	void *tmp, *digest_list = NULL;
 
 	chip = tpm_find_get_ops(chip);
 	if (!chip)
 		return -ENODEV;
 
 	if (chip->flags & TPM_CHIP_FLAG_TPM2) {
-		memset(digest_list, 0, sizeof(digest_list));
-
-		for (i = 0; i < ARRAY_SIZE(chip->active_banks) &&
-			    chip->active_banks[i] != TPM2_ALG_ERROR; i++) {
-			digest_list[i].alg_id = chip->active_banks[i];
-			memcpy(digest_list[i].digest, hash, TPM_DIGEST_SIZE);
+		for (i = 0; i < ARRAY_SIZE(chip->active_banks); i++) {
+			int digest_size;
+			struct tpm2_digest_hdr *digest;
+
+			if (chip->active_banks[i] == TPM2_ALG_ERROR)
+				continue;
+
+			digest_size = tpm2_digest_size(chip->active_banks[i]);
+			if (digest_size < 0)
+				continue;
+
+			digest = (struct tpm2_digest_hdr *)(digest_list + size);
+			size += sizeof(struct tpm2_digest_hdr) + digest_size;
+
+			tmp = krealloc(digest_list, size, GFP_KERNEL);
+			if (!tmp) {
+				kfree(digest_list);
+				return -ENOMEM;
+			}
+			digest_list = tmp;
+			digest->alg_id = chip->active_banks[i];
+			memcpy(digest->digest, hash, digest_size);
 			count++;
 		}
 
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index f27d1f38a93d..178c47763d0c 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -560,7 +560,7 @@ static inline u32 tpm2_rc_value(u32 rc)
 int tpm2_get_timeouts(struct tpm_chip *chip);
 int tpm2_pcr_read(struct tpm_chip *chip, u32 pcr_idx, u8 *res_buf);
 int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, u32 count,
-		    struct tpm2_digest *digests);
+		    struct tpm2_digest_hdr *digests);
 int tpm2_get_random(struct tpm_chip *chip, u8 *dest, size_t max);
 void tpm2_flush_context_cmd(struct tpm_chip *chip, u32 handle,
 			    unsigned int flags);
@@ -584,6 +584,7 @@ int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u32 cc,
 		       u8 *cmd);
 int tpm2_commit_space(struct tpm_chip *chip, struct tpm_space *space,
 		      u32 cc, u8 *buf, size_t *bufsiz);
+int tpm2_digest_size(int algo_id);
 
 int tpm_bios_log_setup(struct tpm_chip *chip);
 void tpm_bios_log_teardown(struct tpm_chip *chip);
diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index a6bec13afa69..c91a0c1ef192 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -226,7 +226,7 @@ struct tpm2_null_auth_area {
  * Return: Same as with tpm_transmit_cmd.
  */
 int tpm2_pcr_extend(struct tpm_chip *chip, u32 pcr_idx, u32 count,
-		    struct tpm2_digest *digests)
+		    struct tpm2_digest_hdr *digests)
 {
 	struct tpm_buf buf;
 	struct tpm2_null_auth_area auth_area;
@@ -1027,3 +1027,16 @@ int tpm2_find_cc(struct tpm_chip *chip, u32 cc)
 
 	return -1;
 }
+
+int tpm2_digest_size(int algo_id)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(tpm2_hash_map); i++) {
+		if (algo_id != tpm2_hash_map[i].tpm_id)
+			continue;
+		return hash_digest_size[tpm2_hash_map[i].crypto_id];
+	}
+
+	return -1;
+}
diff --git a/include/linux/tpm_eventlog.h b/include/linux/tpm_eventlog.h
index b43bd2ea8bab..6363c8b08908 100644
--- a/include/linux/tpm_eventlog.h
+++ b/include/linux/tpm_eventlog.h
@@ -108,20 +108,35 @@ struct tcg_event_field {
 	u8 event[0];
 } __packed;
 
-struct tpm2_digest {
+struct tpm2_digest_hdr {
 	u16 alg_id;
-	u8 digest[SHA512_DIGEST_SIZE];
+	u8 digest[0];
 } __packed;
 
-struct tcg_pcr_event2 {
+struct tcg_pcr_event2_hdr {
 	u32 pcr_idx;
 	u32 event_type;
 	u32 count;
-	struct tpm2_digest digests[TPM2_ACTIVE_PCR_BANKS];
-	struct tcg_event_field event;
+	struct tpm2_digest_hdr digests[0];
 } __packed;
 
-static inline int _calc_tpm2_event_size(struct tcg_pcr_event2 *event,
+struct tcg_algorithm_size {
+	u16 algorithm_id;
+	u16 algorithm_size;
+};
+
+struct tcg_algorithm_info {
+	u8 signature[16];
+	u32 platform_class;
+	u8 spec_version_minor;
+	u8 spec_version_major;
+	u8 spec_errata;
+	u8 uintn_size;
+	u32 number_of_algorithms;
+	struct tcg_algorithm_size digest_sizes[];
+};
+
+static inline int _calc_tpm2_event_size(struct tcg_pcr_event2_hdr *event,
 					struct tcg_pcr_event *event_header)
 {
 	struct tcg_efi_specid_event *efispecid;
-- 
2.20.1.97.g81188d93c3-goog




[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [Linux Kernel]     [Linux Kernel Hardening]     [Linux NFS]     [Linux NILFS]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux SCSI]

  Powered by Linux