diff options
author | Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> | 2017-02-14 22:57:42 +0300 |
---|---|---|
committer | Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com> | 2017-04-03 22:46:01 +0300 |
commit | a147918e79c3a239be59358af659ea9f0959538b (patch) | |
tree | 2502fcfffc23e84d930669accc4c60b0da138c2f /drivers/char/tpm/tpm-interface.c | |
parent | 38eb24ebb01f875f812aa869c4cd62959510111c (diff) | |
download | linux-a147918e79c3a239be59358af659ea9f0959538b.tar.xz |
tpm: move length validation to tpm_transmit()
Check that the length matches the length reported by the response
header already in tpm_transmit() to improve validation.
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Tested-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Reviewed-by: James Bottomley <James.Bottomley@HansenPartnership.com>
Diffstat (limited to 'drivers/char/tpm/tpm-interface.c')
-rw-r--r-- | drivers/char/tpm/tpm-interface.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index bd2128e0b56c..708d3563ee7d 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c @@ -343,6 +343,7 @@ EXPORT_SYMBOL_GPL(tpm_calc_ordinal_duration); ssize_t tpm_transmit(struct tpm_chip *chip, const u8 *buf, size_t bufsiz, unsigned int flags) { + const struct tpm_output_header *header = (void *)buf; ssize_t rc; u32 count, ordinal; unsigned long stop; @@ -406,9 +407,18 @@ ssize_t tpm_transmit(struct tpm_chip *chip, const u8 *buf, size_t bufsiz, out_recv: rc = chip->ops->recv(chip, (u8 *) buf, bufsiz); - if (rc < 0) + if (rc < 0) { dev_err(&chip->dev, "tpm_transmit: tpm_recv: error %zd\n", rc); + goto out; + } else if (rc < TPM_HEADER_SIZE) { + rc = -EFAULT; + goto out; + } + + if (rc != be32_to_cpu(header->length)) + goto out; + out: if (chip->dev.parent) pm_runtime_put_sync(chip->dev.parent); @@ -438,19 +448,13 @@ ssize_t tpm_transmit_cmd(struct tpm_chip *chip, const void *buf, size_t bufsiz, size_t min_rsp_body_length, unsigned int flags, const char *desc) { - const struct tpm_output_header *header; + const struct tpm_output_header *header = buf; int err; ssize_t len; len = tpm_transmit(chip, (const u8 *)buf, bufsiz, flags); if (len < 0) return len; - else if (len < TPM_HEADER_SIZE) - return -EFAULT; - - header = buf; - if (len != be32_to_cpu(header->length)) - return -EFAULT; err = be32_to_cpu(header->return_code); if (err != 0 && desc) |