diff mbox series

[v8,08/17] tpm: call tpm2_flush_space() on error in tpm_try_transmit()

Message ID 20181116123845.15705-9-jarkko.sakkinen@linux.intel.com (mailing list archive)
State New, archived
Headers show
Series Removed nested TPM operations | expand

Commit Message

Jarkko Sakkinen Nov. 16, 2018, 12:38 p.m. UTC
Always call tpm2_flush_space() on failure in tpm_try_transmit() so that
the volatile memory of the TPM gets cleared. If /dev/tpm0 does not have
sufficient permissions (usually it has), this could lead to the leakage
of TPM objects. Through /dev/tpmrm0 this issue does not raise any new
security concerns.

Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
Cc: stable@vger.kernel.org
Fixes: 745b361e989a ("tpm:tpm: infrastructure for TPM spaces")
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
---
 drivers/char/tpm/tpm-interface.c | 29 ++++++++++++-----------------
 drivers/char/tpm/tpm.h           |  1 +
 drivers/char/tpm/tpm2-space.c    |  2 +-
 3 files changed, 14 insertions(+), 18 deletions(-)

Comments

Sasha Levin Nov. 16, 2018, 4:19 p.m. UTC | #1
On Fri, Nov 16, 2018 at 02:38:32PM +0200, Jarkko Sakkinen wrote:
>Always call tpm2_flush_space() on failure in tpm_try_transmit() so that
>the volatile memory of the TPM gets cleared. If /dev/tpm0 does not have
>sufficient permissions (usually it has), this could lead to the leakage
>of TPM objects. Through /dev/tpmrm0 this issue does not raise any new
>security concerns.
>
>Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
>Cc: stable@vger.kernel.org
>Fixes: 745b361e989a ("tpm:tpm: infrastructure for TPM spaces")
>Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
>Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>

Hi Jarkko,

This patch seems to depend on previous patches in this series, but those
were not tagged for stable. Do they also need to be backported? If so,
can you tag them as such?

--
Thanks,
Sasha
Jarkko Sakkinen Nov. 18, 2018, 7:36 a.m. UTC | #2
On Fri, Nov 16, 2018 at 11:19:57AM -0500, Sasha Levin wrote:
> On Fri, Nov 16, 2018 at 02:38:32PM +0200, Jarkko Sakkinen wrote:
> > Always call tpm2_flush_space() on failure in tpm_try_transmit() so that
> > the volatile memory of the TPM gets cleared. If /dev/tpm0 does not have
> > sufficient permissions (usually it has), this could lead to the leakage
> > of TPM objects. Through /dev/tpmrm0 this issue does not raise any new
> > security concerns.
> > 
> > Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
> > Cc: stable@vger.kernel.org
> > Fixes: 745b361e989a ("tpm:tpm: infrastructure for TPM spaces")
> > Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
> > Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
> 
> Hi Jarkko,
> 
> This patch seems to depend on previous patches in this series, but those
> were not tagged for stable. Do they also need to be backported? If so,
> can you tag them as such?

Hi

Is that the preferred approach?

I've usually followed this workflow:

1. Mark patches with a fix to a regression with the fixes tag.
2. If a merge conflict raises, I'll locate the deps.

I've done it this way because often patches can depend on patches
outside the patch set. Anyway, I'm open to change my workflow if
that is required.

/Jarkko
Sasha Levin Nov. 18, 2018, 11:21 p.m. UTC | #3
On Sun, Nov 18, 2018 at 09:36:18AM +0200, Jarkko Sakkinen wrote:
>On Fri, Nov 16, 2018 at 11:19:57AM -0500, Sasha Levin wrote:
>> On Fri, Nov 16, 2018 at 02:38:32PM +0200, Jarkko Sakkinen wrote:
>> > Always call tpm2_flush_space() on failure in tpm_try_transmit() so that
>> > the volatile memory of the TPM gets cleared. If /dev/tpm0 does not have
>> > sufficient permissions (usually it has), this could lead to the leakage
>> > of TPM objects. Through /dev/tpmrm0 this issue does not raise any new
>> > security concerns.
>> >
>> > Cc: James Bottomley <James.Bottomley@HansenPartnership.com>
>> > Cc: stable@vger.kernel.org
>> > Fixes: 745b361e989a ("tpm:tpm: infrastructure for TPM spaces")
>> > Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@linux.intel.com>
>> > Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
>>
>> Hi Jarkko,
>>
>> This patch seems to depend on previous patches in this series, but those
>> were not tagged for stable. Do they also need to be backported? If so,
>> can you tag them as such?
>
>Hi
>
>Is that the preferred approach?
>
>I've usually followed this workflow:
>
>1. Mark patches with a fix to a regression with the fixes tag.
>2. If a merge conflict raises, I'll locate the deps.
>
>I've done it this way because often patches can depend on patches
>outside the patch set. Anyway, I'm open to change my workflow if
>that is required.
>
>/Jarkko

Hi Jarkko,

There's no "preferred" approach really. I try to warn about cases like
this early because the response rates to Greg's "FAILED" email seem to
be low - by the time they are sent out people are done with that code
and have moved on.

In this scenario, for exmaple, this patch would not apply to any stable
tree because it depends on a previous patch in this series that was not
tagged for stable. My hopes are that if I warn you about this early you
can work around this (for example, by marking that prior patch for
stable as well) so you won't need to deal with this patch again in a few
weeks.

There's no need to change anything about your flow if it works for you.

--
Thanks,
Sasha
Jarkko Sakkinen Nov. 19, 2018, 12:57 p.m. UTC | #4
On Sun, Nov 18, 2018 at 06:21:57PM -0500, Sasha Levin wrote:
> There's no "preferred" approach really. I try to warn about cases like
> this early because the response rates to Greg's "FAILED" email seem to
> be low - by the time they are sent out people are done with that code
> and have moved on.
> 
> In this scenario, for exmaple, this patch would not apply to any stable
> tree because it depends on a previous patch in this series that was not
> tagged for stable. My hopes are that if I warn you about this early you
> can work around this (for example, by marking that prior patch for
> stable as well) so you won't need to deal with this patch again in a few
> weeks.
> 
> There's no need to change anything about your flow if it works for you.

Ok, I see. Yeah, it is just how I organize my work. Rather solve the
patch dependency sudoku one time than two times.

When I maintain a subsystem I've thought that it is my responsibility to
always do that and not wait someone else to do it for me :-) That is the
responsibility part of the equation when you have the power to decide
what gets in.

Right now I have two failed merges in my queue that I plan to take care
of them next week.

> Thanks,
> Sasha

/Jarkko
diff mbox series

Patch

diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 11af50646ed1..ef00b698ec02 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -224,14 +224,14 @@  static ssize_t tpm_try_transmit(struct tpm_chip *chip,
 
 	rc = tpm2_prepare_space(chip, space, ordinal, buf);
 	if (rc)
-		goto out;
+		goto out_idle;
 
 	rc = chip->ops->send(chip, buf, count);
 	if (rc < 0) {
 		if (rc != -EPIPE)
 			dev_err(&chip->dev,
 				"%s: tpm_send: error %d\n", __func__, rc);
-		goto out;
+		goto out_space;
 	}
 
 	if (chip->flags & TPM_CHIP_FLAG_IRQ)
@@ -247,7 +247,7 @@  static ssize_t tpm_try_transmit(struct tpm_chip *chip,
 		if (chip->ops->req_canceled(chip, status)) {
 			dev_err(&chip->dev, "Operation Canceled\n");
 			rc = -ECANCELED;
-			goto out;
+			goto out_space;
 		}
 
 		tpm_msleep(TPM_TIMEOUT_POLL);
@@ -257,28 +257,23 @@  static ssize_t tpm_try_transmit(struct tpm_chip *chip,
 	chip->ops->cancel(chip);
 	dev_err(&chip->dev, "Operation Timed out\n");
 	rc = -ETIME;
-	goto out;
+	goto out_space;
 
 out_recv:
 	len = chip->ops->recv(chip, buf, bufsiz);
 	if (len < 0) {
 		rc = len;
-		dev_err(&chip->dev,
-			"tpm_transmit: tpm_recv: error %d\n", rc);
-		goto out;
-	} else if (len < TPM_HEADER_SIZE) {
+		dev_err(&chip->dev, "tpm_transmit: tpm_recv: error %d\n", rc);
+	} else if (len < TPM_HEADER_SIZE || len != be32_to_cpu(header->length))
 		rc = -EFAULT;
-		goto out;
-	}
 
-	if (len != be32_to_cpu(header->length)) {
-		rc = -EFAULT;
-		goto out;
-	}
-
-	rc = tpm2_commit_space(chip, space, ordinal, buf, &len);
+out_space:
+	if (rc)
+		tpm2_flush_space(chip);
+	else
+		rc = tpm2_commit_space(chip, space, ordinal, buf, &len);
 
-out:
+out_idle:
 	/* may fail but do not override previous error value in rc */
 	tpm_go_idle(chip, flags);
 
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 86fa8ac0ae20..92638ec6ec97 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -576,6 +576,7 @@  int tpm2_probe(struct tpm_chip *chip);
 int tpm2_find_cc(struct tpm_chip *chip, u32 cc);
 int tpm2_init_space(struct tpm_space *space);
 void tpm2_del_space(struct tpm_chip *chip, struct tpm_space *space);
+void tpm2_flush_space(struct tpm_chip *chip);
 int tpm2_prepare_space(struct tpm_chip *chip, struct tpm_space *space, u32 cc,
 		       u8 *cmd);
 int tpm2_commit_space(struct tpm_chip *chip, struct tpm_space *space,
diff --git a/drivers/char/tpm/tpm2-space.c b/drivers/char/tpm/tpm2-space.c
index 862ee1ce1755..393d9aadadce 100644
--- a/drivers/char/tpm/tpm2-space.c
+++ b/drivers/char/tpm/tpm2-space.c
@@ -162,7 +162,7 @@  static int tpm2_save_context(struct tpm_chip *chip, u32 handle, u8 *buf,
 	return 0;
 }
 
-static void tpm2_flush_space(struct tpm_chip *chip)
+void tpm2_flush_space(struct tpm_chip *chip)
 {
 	struct tpm_space *space = &chip->work_space;
 	int i;