* [PATCH 6.6] tpm: Lock TPM chip in tpm_pm_suspend() first
@ 2024-12-05 2:26 bin.lan.cn
2024-12-05 13:34 ` Sasha Levin
0 siblings, 1 reply; 2+ messages in thread
From: bin.lan.cn @ 2024-12-05 2:26 UTC (permalink / raw)
To: stable, jarkko
From: Jarkko Sakkinen <jarkko@kernel.org>
[ Upstream commit 9265fed6db601ee2ec47577815387458ef4f047a ]
Setting TPM_CHIP_FLAG_SUSPENDED in the end of tpm_pm_suspend() can be racy
according, as this leaves window for tpm_hwrng_read() to be called while
the operation is in progress. The recent bug report gives also evidence of
this behaviour.
Aadress this by locking the TPM chip before checking any chip->flags both
in tpm_pm_suspend() and tpm_hwrng_read(). Move TPM_CHIP_FLAG_SUSPENDED
check inside tpm_get_random() so that it will be always checked only when
the lock is reserved.
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
Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
Tested-by: Mike Seo <mikeseohyungjin@gmail.com>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
[ Don't call tpm2_end_auth_session() for this function does not exist
in 6.6.y.]
Signed-off-by: Bin Lan <bin.lan.cn@windriver.com>
---
drivers/char/tpm/tpm-chip.c | 4 ----
drivers/char/tpm/tpm-interface.c | 29 +++++++++++++++++++++--------
2 files changed, 21 insertions(+), 12 deletions(-)
diff --git a/drivers/char/tpm/tpm-chip.c b/drivers/char/tpm/tpm-chip.c
index 42b1062e33cd..78999f7f248c 100644
--- a/drivers/char/tpm/tpm-chip.c
+++ b/drivers/char/tpm/tpm-chip.c
@@ -519,10 +519,6 @@ static int tpm_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait)
{
struct tpm_chip *chip = container_of(rng, struct tpm_chip, hwrng);
- /* Give back zero bytes, as TPM chip has not yet fully resumed: */
- if (chip->flags & TPM_CHIP_FLAG_SUSPENDED)
- return 0;
-
return tpm_get_random(chip, data, max);
}
diff --git a/drivers/char/tpm/tpm-interface.c b/drivers/char/tpm/tpm-interface.c
index 66b16d26eecc..c8ea52dfa556 100644
--- a/drivers/char/tpm/tpm-interface.c
+++ b/drivers/char/tpm/tpm-interface.c
@@ -394,6 +394,13 @@ int tpm_pm_suspend(struct device *dev)
if (!chip)
return -ENODEV;
+ rc = tpm_try_get_ops(chip);
+ if (rc) {
+ /* Can be safely set out of locks, as no action cannot race: */
+ chip->flags |= TPM_CHIP_FLAG_SUSPENDED;
+ goto out;
+ }
+
if (chip->flags & TPM_CHIP_FLAG_ALWAYS_POWERED)
goto suspended;
@@ -401,19 +408,18 @@ int tpm_pm_suspend(struct device *dev)
!pm_suspend_via_firmware())
goto suspended;
- rc = tpm_try_get_ops(chip);
- if (!rc) {
- if (chip->flags & TPM_CHIP_FLAG_TPM2)
- tpm2_shutdown(chip, TPM2_SU_STATE);
- else
- rc = tpm1_pm_suspend(chip, tpm_suspend_pcr);
-
- tpm_put_ops(chip);
+ if (chip->flags & TPM_CHIP_FLAG_TPM2) {
+ tpm2_shutdown(chip, TPM2_SU_STATE);
+ goto suspended;
}
+ rc = tpm1_pm_suspend(chip, tpm_suspend_pcr);
+
suspended:
chip->flags |= TPM_CHIP_FLAG_SUSPENDED;
+ tpm_put_ops(chip);
+out:
if (rc)
dev_err(dev, "Ignoring error %d while suspending\n", rc);
return 0;
@@ -462,11 +468,18 @@ int tpm_get_random(struct tpm_chip *chip, u8 *out, size_t max)
if (!chip)
return -ENODEV;
+ /* Give back zero bytes, as TPM chip has not yet fully resumed: */
+ if (chip->flags & TPM_CHIP_FLAG_SUSPENDED) {
+ rc = 0;
+ goto out;
+ }
+
if (chip->flags & TPM_CHIP_FLAG_TPM2)
rc = tpm2_get_random(chip, out, max);
else
rc = tpm1_get_random(chip, out, max);
+out:
tpm_put_ops(chip);
return rc;
}
--
2.43.0
^ permalink raw reply related [flat|nested] 2+ messages in thread* Re: [PATCH 6.6] tpm: Lock TPM chip in tpm_pm_suspend() first
2024-12-05 2:26 [PATCH 6.6] tpm: Lock TPM chip in tpm_pm_suspend() first bin.lan.cn
@ 2024-12-05 13:34 ` Sasha Levin
0 siblings, 0 replies; 2+ messages in thread
From: Sasha Levin @ 2024-12-05 13:34 UTC (permalink / raw)
To: stable; +Cc: bin.lan.cn, Sasha Levin
[ Sasha's backport helper bot ]
Hi,
The upstream commit SHA1 provided is correct: 9265fed6db601ee2ec47577815387458ef4f047a
WARNING: Author mismatch between patch and upstream commit:
Backport author: bin.lan.cn@eng.windriver.com
Commit author: Jarkko Sakkinen <jarkko@kernel.org>
Status in newer kernel trees:
6.12.y | Present (exact SHA1)
6.11.y | Present (different SHA1: bc203fe416ab)
6.6.y | Not found
Note: The patch differs from the upstream commit:
---
1: 9265fed6db601 ! 1: 7fcb4bafb7f2d tpm: Lock TPM chip in tpm_pm_suspend() first
@@ Metadata
## Commit message ##
tpm: Lock TPM chip in tpm_pm_suspend() first
+ [ Upstream commit 9265fed6db601ee2ec47577815387458ef4f047a ]
+
Setting TPM_CHIP_FLAG_SUSPENDED in the end of tpm_pm_suspend() can be racy
according, as this leaves window for tpm_hwrng_read() to be called while
the operation is in progress. The recent bug report gives also evidence of
@@ Commit message
Reviewed-by: Jerry Snitselaar <jsnitsel@redhat.com>
Tested-by: Mike Seo <mikeseohyungjin@gmail.com>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
+ [ Don't call tpm2_end_auth_session() for this function does not exist
+ in 6.6.y.]
+ Signed-off-by: Bin Lan <bin.lan.cn@windriver.com>
## drivers/char/tpm/tpm-chip.c ##
@@ drivers/char/tpm/tpm-chip.c: static int tpm_hwrng_read(struct hwrng *rng, void *data, size_t max, bool wait)
@@ drivers/char/tpm/tpm-interface.c: int tpm_pm_suspend(struct device *dev)
- rc = tpm_try_get_ops(chip);
- if (!rc) {
-- if (chip->flags & TPM_CHIP_FLAG_TPM2) {
-- tpm2_end_auth_session(chip);
+- if (chip->flags & TPM_CHIP_FLAG_TPM2)
- tpm2_shutdown(chip, TPM2_SU_STATE);
-- } else {
+- else
- rc = tpm1_pm_suspend(chip, tpm_suspend_pcr);
-- }
-
- tpm_put_ops(chip);
+ if (chip->flags & TPM_CHIP_FLAG_TPM2) {
-+ tpm2_end_auth_session(chip);
+ tpm2_shutdown(chip, TPM2_SU_STATE);
+ goto suspended;
}
---
Results of testing on various branches:
| Branch | Patch Apply | Build Test |
|---------------------------|-------------|------------|
| stable/linux-6.6.y | Success | Success |
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2024-12-05 14:45 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2024-12-05 2:26 [PATCH 6.6] tpm: Lock TPM chip in tpm_pm_suspend() first bin.lan.cn
2024-12-05 13:34 ` Sasha Levin
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox