All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jarkko Sakkinen <jarkko@kernel.org>
To: Sven van Ashbrook <svenva@chromium.org>
Cc: Peter Huewe <peterhuewe@gmx.de>, Jason Gunthorpe <jgg@ziepe.ca>,
	Hao Wu <hao.wu@rubrik.com>, Yi Chou <yich@google.com>,
	Andrey Pronin <apronin@chromium.org>,
	James Morris <james.morris@microsoft.com>,
	stable@vger.kernel.org, linux-integrity@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH] tpm: fix potential race condition in suspend/resume
Date: Thu, 11 Aug 2022 08:02:02 +0300	[thread overview]
Message-ID: <YvSNSs84wMRZ8Fa9@kernel.org> (raw)
In-Reply-To: <20220809193921.544546-1-svenva@chromium.org>

On Tue, Aug 09, 2022 at 07:39:18PM +0000, Sven van Ashbrook wrote:
> Concurrent accesses to the tpm chip are prevented by allowing only a
> single thread at a time to obtain a tpm chip reference through
> tpm_try_get_ops(). However, the tpm's suspend function does not use
> this mechanism, so when the tpm api is called by a kthread which
> does not get frozen on suspend (such as the hw_random kthread)
> it's possible that the tpm is used when already in suspend, or
> in use while in the process of suspending.
> 
> This is seen on certain ChromeOS platforms - low-probability warnings
> are generated during suspend. In this case, the tpm attempted to read data
> from a tpm chip on an already-suspended bus.
> 
>   i2c_designware i2c_designware.1: Transfer while suspended
> 
> Fix:
> 1. prevent concurrent execution of tpm accesses and suspend/
>    resume, by letting suspend/resume grab the tpm_mutex.
> 2. before commencing a tpm access, check if the tpm chip is already
>    suspended. Fail with -EAGAIN if so.
> 
> Tested by running 6000 suspend/resume cycles back-to-back on a
> ChromeOS "brya" device. The intermittent warnings reliably
> disappear after applying this patch. No system issues were observed.
> 
> Cc: <stable@vger.kernel.org>
> Fixes: e891db1a18bf ("tpm: turn on TPM on suspend for TPM 1.x")
> Signed-off-by: Sven van Ashbrook <svenva@chromium.org>
> ---
>  drivers/char/tpm/tpm-interface.c | 16 ++++++++++++++++
>  include/linux/tpm.h              |  2 ++
>  2 files changed, 18 insertions(+)
> 
> diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
> index 1621ce818705..16ca490fd483 100644
> --- a/drivers/char/tpm/tpm-interface.c
> +++ b/drivers/char/tpm/tpm-interface.c
> @@ -82,6 +82,11 @@ static ssize_t tpm_try_transmit(struct tpm_chip *chip, void *buf, size_t bufsiz)
>  		return -E2BIG;
>  	}
>  
> +	if (chip->is_suspended) {
> +		dev_info(&chip->dev, "blocking transmit while suspended\n");
> +		return -EAGAIN;
> +	}
> +
>  	rc = chip->ops->send(chip, buf, count);
>  	if (rc < 0) {
>  		if (rc != -EPIPE)
> @@ -394,6 +399,8 @@ int tpm_pm_suspend(struct device *dev)
>  	if (!chip)
>  		return -ENODEV;
>  
> +	mutex_lock(&chip->tpm_mutex);
> +
>  	if (chip->flags & TPM_CHIP_FLAG_ALWAYS_POWERED)
>  		goto suspended;
>  
> @@ -411,6 +418,11 @@ int tpm_pm_suspend(struct device *dev)
>  	}
>  
>  suspended:
> +	if (!rc)
> +		chip->is_suspended = true;
> +
> +	mutex_unlock(&chip->tpm_mutex);
> +
>  	return rc;
>  }
>  EXPORT_SYMBOL_GPL(tpm_pm_suspend);
> @@ -426,6 +438,10 @@ int tpm_pm_resume(struct device *dev)
>  	if (chip == NULL)
>  		return -ENODEV;
>  
> +	mutex_lock(&chip->tpm_mutex);
> +	chip->is_suspended = false;
> +	mutex_unlock(&chip->tpm_mutex);
> +
>  	return 0;
>  }
>  EXPORT_SYMBOL_GPL(tpm_pm_resume);
> diff --git a/include/linux/tpm.h b/include/linux/tpm.h
> index d7c67581929f..0fbc1a43ae80 100644
> --- a/include/linux/tpm.h
> +++ b/include/linux/tpm.h
> @@ -131,6 +131,8 @@ struct tpm_chip {
>  	int dev_num;		/* /dev/tpm# */
>  	unsigned long is_open;	/* only one allowed */
>  
> +	bool is_suspended;
> +
>  	char hwrng_name[64];
>  	struct hwrng hwrng;
>  
> -- 
> 2.37.1.559.g78731f0fdb-goog
> 

What about adding TPM_CHIP_FLAG_SUSPENDED instead?

BR, Jarkko

  reply	other threads:[~2022-08-11  5:02 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-08-09 19:39 [PATCH] tpm: fix potential race condition in suspend/resume Sven van Ashbrook
2022-08-11  5:02 ` Jarkko Sakkinen [this message]
2022-08-11 13:09   ` Sven van Ashbrook
2022-08-14 17:59     ` 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=YvSNSs84wMRZ8Fa9@kernel.org \
    --to=jarkko@kernel.org \
    --cc=apronin@chromium.org \
    --cc=hao.wu@rubrik.com \
    --cc=james.morris@microsoft.com \
    --cc=jgg@ziepe.ca \
    --cc=linux-integrity@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=peterhuewe@gmx.de \
    --cc=stable@vger.kernel.org \
    --cc=svenva@chromium.org \
    --cc=yich@google.com \
    /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.