[tpmdd-devel,03/10] tpm: tpm2_pcr_read: check size of response before accessing data
diff mbox

Message ID 1484057900-17871-3-git-send-email-stefanb@linux.vnet.ibm.com
State New
Headers show

Commit Message

Stefan Berger Jan. 10, 2017, 2:18 p.m. UTC
Check the size of the response before accessing data in the
response packet. This is to avoid accessing data beyond the
end of the response.

Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
---
 drivers/char/tpm/tpm2-cmd.c | 7 +++++++
 1 file changed, 7 insertions(+)

Comments

Jason Gunthorpe Jan. 10, 2017, 4:18 p.m. UTC | #1
On Tue, Jan 10, 2017 at 09:18:13AM -0500, Stefan Berger wrote:
> Check the size of the response before accessing data in the
> response packet. This is to avoid accessing data beyond the
> end of the response.

IMHO you should chnage the signature for
tpm_transmit_cmd to be:

ssize_t tpm_transmit_cmd(struct tpm_chip *chip,
  void *iobuf, size_t tx_len,
  size_t min_rx_len,
  unsigned int flags,
  const char *desc);

And then fold this repeated:

>  	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0,
>  			      "attempting to read a pcr value");
> +	if (rc == 0 &&
> +	    be32_to_cpu(cmd.header.out.length) < TPM2_PCR_READ_OUT_SIZE)
> +		return -EFAULT;

test into tpm_transmit_cmd and now we require every single caller to
specify the minimum command length.

You can fold all of that into one patch, IMHO. Easier for stable.

Jason

------------------------------------------------------------------------------
Developer Access Program for Intel Xeon Phi Processors
Access to Intel Xeon Phi processor-based developer platforms.
With one year of Intel Parallel Studio XE.
Training and support from Colfax.
Order your platform today. http://sdm.link/xeonphi

Patch
diff mbox

diff --git a/drivers/char/tpm/tpm2-cmd.c b/drivers/char/tpm/tpm2-cmd.c
index d302f06..e3f760c 100644
--- a/drivers/char/tpm/tpm2-cmd.c
+++ b/drivers/char/tpm/tpm2-cmd.c
@@ -248,6 +248,10 @@  static const u8 tpm2_ordinal_duration[TPM2_CC_LAST - TPM2_CC_FIRST + 1] = {
 	(sizeof(struct tpm_input_header) + \
 	 sizeof(struct tpm2_pcr_read_in))
 
+#define TPM2_PCR_READ_OUT_SIZE \
+	(sizeof(struct tpm_output_header) + \
+	 sizeof(struct tpm2_pcr_read_out))
+
 static const struct tpm_input_header tpm2_pcrread_header = {
 	.tag = cpu_to_be16(TPM2_ST_NO_SESSIONS),
 	.length = cpu_to_be32(TPM2_PCR_READ_IN_SIZE),
@@ -282,6 +286,9 @@  int tpm2_pcr_read(struct tpm_chip *chip, int pcr_idx, u8 *res_buf)
 
 	rc = tpm_transmit_cmd(chip, &cmd, sizeof(cmd), 0,
 			      "attempting to read a pcr value");
+	if (rc == 0 &&
+	    be32_to_cpu(cmd.header.out.length) < TPM2_PCR_READ_OUT_SIZE)
+		return -EFAULT;
 	if (rc == 0) {
 		buf = cmd.params.pcrread_out.digest;
 		memcpy(res_buf, buf, TPM_DIGEST_SIZE);