From: Jeremy Boone jeremy.boone@nccgroup.trust
commit 3be23274755ee85771270a23af7691dc9b3a95db upstream
Discrete TPMs are often connected over slow serial buses which, on some platforms, can have glitches causing bit flips. If a bit does flip it could cause an overrun if it's in one of the size parameters, so sanity check that we're not overrunning the provided buffer when doing a memcpy().
Signed-off-by: Jeremy Boone jeremy.boone@nccgroup.trust Cc: stable@vger.kernel.org Signed-off-by: James Bottomley James.Bottomley@HansenPartnership.com Reviewed-by: Jarkko Sakkinen jarkko.sakkinen@linux.intel.com Tested-by: Jarkko Sakkinen jarkko.sakkinen@linux.intel.com Signed-off-by: Jarkko Sakkinen jarkko.sakkinen@linux.intel.com --- Backported to v4.4. v2: fixed the upstream ID drivers/char/tpm/tpm-interface.c | 5 +++++ drivers/char/tpm/tpm2-cmd.c | 6 ++++++ 2 files changed, 11 insertions(+)
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c index aaa5fa95dede..36afc1a21699 100644 --- a/drivers/char/tpm/tpm-interface.c +++ b/drivers/char/tpm/tpm-interface.c @@ -1040,6 +1040,11 @@ int tpm_get_random(u32 chip_num, u8 *out, size_t max) break;
recd = be32_to_cpu(tpm_cmd.params.getrandom_out.rng_data_len); + if (recd > num_bytes) { + total = -EFAULT; + break; + } + memcpy(dest, tpm_cmd.params.getrandom_out.rng_data, recd);
dest += recd; diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c index 286bd090a488..389a009b83f2 100644 --- a/drivers/char/tpm/tpm2-cmd.c +++ b/drivers/char/tpm/tpm2-cmd.c @@ -622,6 +622,11 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip, if (!rc) { data_len = be16_to_cpup( (__be16 *) &buf.data[TPM_HEADER_SIZE + 4]); + if (data_len < MIN_KEY_SIZE || data_len > MAX_KEY_SIZE + 1) { + rc = -EFAULT; + goto out; + } + data = &buf.data[TPM_HEADER_SIZE + 6];
memcpy(payload->key, data, data_len - 1); @@ -629,6 +634,7 @@ static int tpm2_unseal_cmd(struct tpm_chip *chip, payload->migratable = data[data_len - 1]; }
+out: tpm_buf_destroy(&buf); return rc; }