Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

tpm: fix checks for policy digest existence in tpm2_seal_trusted()

In my original patch sealing with policy was done with dynamically
allocated buffer that I changed later into an array so the checks in
tpm2-cmd.c became invalid. This patch fixes the issue.

Fixes: 5beb0c435bdd ("keys, trusted: seal with a TPM2 authorization policy")
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Acked-by: Peter Huewe <peterhuewe@gmx.de>

+10 -15
+4 -8
drivers/char/tpm/tpm2-cmd.c
··· 478 478 tpm_buf_append_u8(&buf, payload->migratable); 479 479 480 480 /* public */ 481 - if (options->policydigest) 482 - tpm_buf_append_u16(&buf, 14 + options->digest_len); 483 - else 484 - tpm_buf_append_u16(&buf, 14); 485 - 481 + tpm_buf_append_u16(&buf, 14 + options->policydigest_len); 486 482 tpm_buf_append_u16(&buf, TPM2_ALG_KEYEDHASH); 487 483 tpm_buf_append_u16(&buf, hash); 488 484 489 485 /* policy */ 490 - if (options->policydigest) { 486 + if (options->policydigest_len) { 491 487 tpm_buf_append_u32(&buf, 0); 492 - tpm_buf_append_u16(&buf, options->digest_len); 488 + tpm_buf_append_u16(&buf, options->policydigest_len); 493 489 tpm_buf_append(&buf, options->policydigest, 494 - options->digest_len); 490 + options->policydigest_len); 495 491 } else { 496 492 tpm_buf_append_u32(&buf, TPM2_ATTR_USER_WITH_AUTH); 497 493 tpm_buf_append_u16(&buf, 0);
+1 -1
include/keys/trusted-type.h
··· 38 38 unsigned char pcrinfo[MAX_PCRINFO_SIZE]; 39 39 int pcrlock; 40 40 uint32_t hash; 41 - uint32_t digest_len; 41 + uint32_t policydigest_len; 42 42 unsigned char policydigest[MAX_DIGEST_SIZE]; 43 43 uint32_t policyhandle; 44 44 };
+5 -6
security/keys/trusted.c
··· 744 744 unsigned long handle; 745 745 unsigned long lock; 746 746 unsigned long token_mask = 0; 747 + unsigned int digest_len; 747 748 int i; 748 749 int tpm2; 749 750 ··· 753 752 return tpm2; 754 753 755 754 opt->hash = tpm2 ? HASH_ALGO_SHA256 : HASH_ALGO_SHA1; 756 - opt->digest_len = hash_digest_size[opt->hash]; 757 755 758 756 while ((p = strsep(&c, " \t"))) { 759 757 if (*p == '\0' || *p == ' ' || *p == '\t') ··· 812 812 for (i = 0; i < HASH_ALGO__LAST; i++) { 813 813 if (!strcmp(args[0].from, hash_algo_name[i])) { 814 814 opt->hash = i; 815 - opt->digest_len = 816 - hash_digest_size[opt->hash]; 817 815 break; 818 816 } 819 817 } ··· 823 825 } 824 826 break; 825 827 case Opt_policydigest: 826 - if (!tpm2 || 827 - strlen(args[0].from) != (2 * opt->digest_len)) 828 + digest_len = hash_digest_size[opt->hash]; 829 + if (!tpm2 || strlen(args[0].from) != (2 * digest_len)) 828 830 return -EINVAL; 829 831 res = hex2bin(opt->policydigest, args[0].from, 830 - opt->digest_len); 832 + digest_len); 831 833 if (res < 0) 832 834 return -EINVAL; 835 + opt->policydigest_len = digest_len; 833 836 break; 834 837 case Opt_policyhandle: 835 838 if (!tpm2)