tpm: fix checks for policy digest existence in tpm2_seal_trusted()
authorJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Wed, 6 Jan 2016 14:43:30 +0000 (16:43 +0200)
committerJarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Wed, 10 Feb 2016 02:10:55 +0000 (04:10 +0200)
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>
drivers/char/tpm/tpm2-cmd.c
include/keys/trusted-type.h
security/keys/trusted.c

index 45a6340..66e04b4 100644 (file)
@@ -478,20 +478,16 @@ int tpm2_seal_trusted(struct tpm_chip *chip,
        tpm_buf_append_u8(&buf, payload->migratable);
 
        /* public */
-       if (options->policydigest)
-               tpm_buf_append_u16(&buf, 14 + options->digest_len);
-       else
-               tpm_buf_append_u16(&buf, 14);
-
+       tpm_buf_append_u16(&buf, 14 + options->policydigest_len);
        tpm_buf_append_u16(&buf, TPM2_ALG_KEYEDHASH);
        tpm_buf_append_u16(&buf, hash);
 
        /* policy */
-       if (options->policydigest) {
+       if (options->policydigest_len) {
                tpm_buf_append_u32(&buf, 0);
-               tpm_buf_append_u16(&buf, options->digest_len);
+               tpm_buf_append_u16(&buf, options->policydigest_len);
                tpm_buf_append(&buf, options->policydigest,
-                              options->digest_len);
+                              options->policydigest_len);
        } else {
                tpm_buf_append_u32(&buf, TPM2_ATTR_USER_WITH_AUTH);
                tpm_buf_append_u16(&buf, 0);
index 42cf2d9..4ea7e55 100644 (file)
@@ -38,7 +38,7 @@ struct trusted_key_options {
        unsigned char pcrinfo[MAX_PCRINFO_SIZE];
        int pcrlock;
        uint32_t hash;
-       uint32_t digest_len;
+       uint32_t policydigest_len;
        unsigned char policydigest[MAX_DIGEST_SIZE];
        uint32_t policyhandle;
 };
index 0dcab20..90d6175 100644 (file)
@@ -744,6 +744,7 @@ static int getoptions(char *c, struct trusted_key_payload *pay,
        unsigned long handle;
        unsigned long lock;
        unsigned long token_mask = 0;
+       unsigned int digest_len;
        int i;
        int tpm2;
 
@@ -752,7 +753,6 @@ static int getoptions(char *c, struct trusted_key_payload *pay,
                return tpm2;
 
        opt->hash = tpm2 ? HASH_ALGO_SHA256 : HASH_ALGO_SHA1;
-       opt->digest_len = hash_digest_size[opt->hash];
 
        while ((p = strsep(&c, " \t"))) {
                if (*p == '\0' || *p == ' ' || *p == '\t')
@@ -812,8 +812,6 @@ static int getoptions(char *c, struct trusted_key_payload *pay,
                        for (i = 0; i < HASH_ALGO__LAST; i++) {
                                if (!strcmp(args[0].from, hash_algo_name[i])) {
                                        opt->hash = i;
-                                       opt->digest_len =
-                                               hash_digest_size[opt->hash];
                                        break;
                                }
                        }
@@ -825,13 +823,14 @@ static int getoptions(char *c, struct trusted_key_payload *pay,
                        }
                        break;
                case Opt_policydigest:
-                       if (!tpm2 ||
-                           strlen(args[0].from) != (2 * opt->digest_len))
+                       digest_len = hash_digest_size[opt->hash];
+                       if (!tpm2 || strlen(args[0].from) != (2 * digest_len))
                                return -EINVAL;
                        res = hex2bin(opt->policydigest, args[0].from,
-                                     opt->digest_len);
+                                     digest_len);
                        if (res < 0)
                                return -EINVAL;
+                       opt->policydigest_len = digest_len;
                        break;
                case Opt_policyhandle:
                        if (!tpm2)