tpm: Lock TPM chip in tpm_pm_suspend() first
Subsystems (3)
Jarkko Sakkinen
maintainerPATCH v2 1/1 tpm: Lock TPM chip in tpm_pm_suspend() first
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.
To address this, lock the TPM chip before checking any possible flags. This will guarantee that tpm_hwrng_read() and tpm_pm_suspend() won't conflict with each other.
Cc [email protected] # v6.4+
Fixes 99d464506255 ("tpm: Prevent hwrng from activating during resume")
Reported-by Mike Seo <[email protected]>
Signed-off-by Jarkko Sakkinen <[email protected]>
---
v2:
- Addressed my own remark:
https://lore.kernel.org/linux-integrity/[email protected]/
--- drivers/char/tpm/tpm-interface.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-)
drivers/char/tpm/tpm-interface.c +16 -10
@@ -370,6 +370,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;
@@ -377,23 +384,22 @@ 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_end_auth_session (chip); -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_end_auth_session (chip); +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 ; }EXPORT_SYMBOL_GPL (tpm_pm_suspend);
Signature · 1 line
2.47.0