From: "Jarkko Sakkinen" <jarkko@kernel.org>
To: "Jerry Snitselaar" <jsnitsel@redhat.com>
Cc: "Peter Huewe" <peterhuewe@gmx.de>,
"Jason Gunthorpe" <jgg@ziepe.ca>, <stable@vger.kernel.org>,
"Mike Seo" <mikeseohyungjin@gmail.com>,
"open list:TPM DEVICE DRIVER" <linux-integrity@vger.kernel.org>,
"open list" <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH] tpm: set TPM_CHIP_FLAG_SUSPENDED early
Date: Thu, 31 Oct 2024 17:59:43 +0200 [thread overview]
Message-ID: <D5A473YHVE8A.W40YN3RC5BYN@kernel.org> (raw)
In-Reply-To: <cspzjpjurwlpgd7n45mt224saf5p3dq3nrhkmhbyhmnq7iky4q@ahc66xqfnnab>
On Thu Oct 31, 2024 at 5:28 PM EET, Jerry Snitselaar wrote:
> On Thu, Oct 31, 2024 at 08:02:37AM -0700, Jerry Snitselaar wrote:
> > On Thu, Oct 31, 2024 at 01:36:46AM +0200, Jarkko Sakkinen wrote:
> > > On Wed Oct 30, 2024 at 10:09 PM EET, Jerry Snitselaar wrote:
> > > > On Wed, Oct 30, 2024 at 12:36:47AM +0200, Jarkko Sakkinen wrote:
> > > > > Setting TPM_CHIP_FLAG_SUSPENDED in the end of tpm_pm_suspend() can be racy
> > > > > according to the bug report, as this leaves window for tpm_hwrng_read() to
> > > > > be called while the operation is in progress. Move setting of the flag
> > > > > into the beginning.
> > > > >
> > > > > Cc: stable@vger.kernel.org # v6.4+
> > > > > Fixes: 99d464506255 ("tpm: Prevent hwrng from activating during resume")
> > > > > Reported-by: Mike Seo <mikeseohyungjin@gmail.com>
> > > > > Closes: https://bugzilla.kernel.org/show_bug.cgi?id=219383
> > > > > Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
> > > > > ---
> > > > > drivers/char/tpm/tpm-interface.c | 4 ++--
> > > > > 1 file changed, 2 insertions(+), 2 deletions(-)
> > > > >
> > > > > diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
> > > > > index 8134f002b121..3f96bc8b95df 100644
> > > > > --- a/drivers/char/tpm/tpm-interface.c
> > > > > +++ b/drivers/char/tpm/tpm-interface.c
> > > > > @@ -370,6 +370,8 @@ int tpm_pm_suspend(struct device *dev)
> > > > > if (!chip)
> > > > > return -ENODEV;
> > > > >
> > > > > + chip->flags |= TPM_CHIP_FLAG_SUSPENDED;
> > > > > +
> > > > > if (chip->flags & TPM_CHIP_FLAG_ALWAYS_POWERED)
> > > > > goto suspended;
> > > > >
> > > > > @@ -390,8 +392,6 @@ int tpm_pm_suspend(struct device *dev)
> > > > > }
> > > > >
> > > > > suspended:
> > > > > - chip->flags |= TPM_CHIP_FLAG_SUSPENDED;
> > > > > -
> > > > > if (rc)
> > > > > dev_err(dev, "Ignoring error %d while suspending\n", rc);
> > > > > return 0;
> > > > > --
> > > > > 2.47.0
> > > > >
> > > >
> > > > Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
> > >
> > > Thanks but I actually started to look at the function:
> > >
> > > https://elixir.bootlin.com/linux/v6.11.5/source/drivers/char/tpm/tpm-interface.c#L365
> > >
> > > The absolutely safe-play way considering concurrency would be
> > > to do tpm_try_get_ops() before checking any flags. That way
> > > tpm_hwrng_read() is guaranteed not conflict.
> > >
> > > So the way I would fix this instead would be to (untested
> > > wrote inline here):
> > >
> > > int tpm_pm_suspend(struct device *dev)
> > > {
> > > struct tpm_chip *chip = dev_get_drvdata(dev);
> > > int rc = 0;
> > >
> > > if (!chip)
> > > return -ENODEV;
> > >
> > > rc = tpm_try_get_ops(chip);
> > > if (rc) {
> > > chip->flags = |= TPM_CHIP_FLAG_SUSPENDED;
> > > return rc;
> > > }
> > >
> > > /* ... */
> > >
> > > suspended:
> > > chip->flags |= TPM_CHIP_FLAG_SUSPENDED;
> > > tpm_put_ops(chip);
> > >
> > > It does not really affect performance but guarantees that
> > > tpm_hwrng_read() is guaranteed either fully finish or
> > > never happens given that both sides take chip->lock.
> > >
> > > So I'll put one more round of this and then this should be
> > > stable and fully fixed.
> > >
> > > BR, Jarkko
> >
> > Ah, yeah better to set it while it has the mutex. That should still be
> > 'if (!rc)' after the tpm_try_get_ops() right? (I'm assuming that is just
> > a transcription error).
> >
> > Regards,
> > Jerry
> >
>
> It has been a while since I've looked at TPM code. Since
> tpm_hwrng_read doesn't check the flag with the mutex held is there a
> point later where it will bail out if the suspend has occurred? I'm
> wondering if the check for the suspend flag in tpm_hwrng_read should
> be after the tpm_find_get_ops in tpm_get_random.
Right, I ignored that side in v2. Yeah, I agree that in both cases
it would be best that all checks are done when the lock is taken.
It means open-coding tpm2_get_random() but I think it is anyway
good idea (as tpm_get_random() is meant for outside callers).
> Regards,
> Jerry
BR, Jarkko
next prev parent reply other threads:[~2024-10-31 15:59 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-10-29 22:36 [PATCH] tpm: set TPM_CHIP_FLAG_SUSPENDED early Jarkko Sakkinen
2024-10-30 20:09 ` Jerry Snitselaar
2024-10-30 23:36 ` Jarkko Sakkinen
2024-10-31 15:02 ` Jerry Snitselaar
2024-10-31 15:28 ` Jerry Snitselaar
2024-10-31 15:59 ` Jarkko Sakkinen [this message]
2024-10-31 16:02 ` Jarkko Sakkinen
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=D5A473YHVE8A.W40YN3RC5BYN@kernel.org \
--to=jarkko@kernel.org \
--cc=jgg@ziepe.ca \
--cc=jsnitsel@redhat.com \
--cc=linux-integrity@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mikeseohyungjin@gmail.com \
--cc=peterhuewe@gmx.de \
--cc=stable@vger.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.