Linux-Integrity Archive mirror
 help / color / mirror / Atom feed
From: "Daniel P. Smith" <dpsmith@apertussolutions.com>
To: Jason Gunthorpe <jgg@ziepe.ca>,
	Jarkko Sakkinen <jarkko@kernel.org>,
	Sasha Levin <sashal@kernel.org>,
	Lino Sanfilippo <l.sanfilippo@kunbus.com>,
	linux-integrity@vger.kernel.org, linux-kernel@vger.kernel.org
Cc: "Daniel P. Smith" <dpsmith@apertussolutions.com>,
	Ross Philipson <ross.philipson@oracle.com>,
	Kanth Ghatraju <kanth.ghatraju@oracle.com>,
	Peter Huewe <peterhuewe@gmx.de>
Subject: [PATCH v2 0/3] tpm: make locality handling resilient
Date: Wed, 31 Jan 2024 12:19:29 -0500	[thread overview]
Message-ID: <20240131171929.18799-1-dpsmith@apertussolutions.com> (raw)

When the kernel is started by a loader that leaves a locality other than
Locality0 open, for example Intel TXT SINIT ACM leaves Locality2 open, this
triggers a failure condition in the initialization of the TPM driver. The
result being that despite calls to request/relinquish locality, the locality
that was open at startup is never open/closed. The impact for an Intel TXT
platform is that after SMX mode is exited, access to the Locality2 register
space is blocked, and the TPM is locked in Locality 2 rendering the TPM
unusable.

The ability to trigger this failure condition was introduced in commit
933bfc5ad213, which introduced a locality counter to control when locality
requests were actually sent to the TPM. The commit introduces a series of
missing or incorrect protections in place for incrementing and decrementing the
counter. The protection around incrementing the counter was protected with an
incorrect check. The check was incorrect in two ways, 1.) it assumed that zero
was the only successful value that would be returned by
__tpm_tis_request_locality() and 2.) was evaluated outside the if block under
which __tpm_tis_request_locality() is called. The effect of (1) is that
__tpm_tis_request_locality() in fact returns the locality number that was
requested, e.g. 1-4, and therefore the protection check would fail and the
counter does not get incremented. The effect of (2) is a combination with the
ret variable being initialized to 0 and the counter not being 0. The result is
that __tpm_tis_request_locality() does not get called, but the counter is still
incremented.

Another effect seen is an indirect result of commit 933bfc5ad213 and is due to
locality being tracked in two different locations. The first is at the TIS
layer in struct tpm_tis_data and at the chip layer in struct tpm_chip. The
failures experienced by commit 933bfc5ad213 causes the locality value in these
two locations to fall out of sync with the value in tpm_tis_data reflecting
Locality0 and struct tpm_chip having a value of -1, no locality open.

This series seeks to address these conditions by introducing a protection
against underflowing the locality counter. The closing of all localities at the
beginning of initialization to begin with the TPM in the state expected by the
sequencing codified in the initialization. Lastly to adjust the return error
codes from __tpm_tis_request_locality() and tpm_tis_request_locality() to
ensure they are consistent and that the locality counter is only incremented
for a successful call to __tpm_tis_request_locality().

Changes in v2:
- split into three patches
- adjust code comments per review
- dropped incorrect return value change for tpm_request_locality in tpm-chip.c
- additional -1 replacement in __tpm_tis_relinquish_locality
- changed -EIO to -EBUSY, which is more appropriate, in tpm_tis_relinquish_locality

Daniel P. Smith (3):
  tpm: protect against locality counter underflow
  tpm: ensure tpm is in known state at startup
  tpm: make locality request return value consistent

 drivers/char/tpm/tpm_tis_core.c | 25 +++++++++++++++++++------
 include/linux/tpm.h             |  6 ++++++
 2 files changed, 25 insertions(+), 6 deletions(-)

-- 
2.30.2


                 reply	other threads:[~2024-01-31 17:19 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240131171929.18799-1-dpsmith@apertussolutions.com \
    --to=dpsmith@apertussolutions.com \
    --cc=jarkko@kernel.org \
    --cc=jgg@ziepe.ca \
    --cc=kanth.ghatraju@oracle.com \
    --cc=l.sanfilippo@kunbus.com \
    --cc=linux-integrity@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=peterhuewe@gmx.de \
    --cc=ross.philipson@oracle.com \
    --cc=sashal@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).