Hi,
This pull request fixes a race condition between tpm_pm_suspend() and tpm_hwrng_read() (I think for good now): https://bugzilla.kernel.org/show_bug.cgi?id=219383 BR, Jarkko -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQRE6pSOnaBC00OEHEIaerohdGur0gUCZygPzAAKCRAaerohdGur 0pVIAQCiPAk03Cz7cHmeDfWr19VJfazDdqYSfm2muGkrK1HamQEAhbruhFlAWChZ G6PGBppQkGmGcwLk4LneGtr4FX7yPwY= =6DaV -----END PGP SIGNATURE----- Merge tag 'tpmdd-next-6.12-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd Pull tpm fix from Jarkko Sakkinen: "Fix a race condition between tpm_pm_suspend() and tpm_hwrng_read() (I think for good now)" * tag 'tpmdd-next-6.12-rc7' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd: tpm: Lock TPM chip in tpm_pm_suspend() first
This commit is contained in:
commit
a0339404fd
@ -525,10 +525,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);
|
||||
}
|
||||
|
||||
|
@ -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,21 +384,19 @@ 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;
|
||||
@ -440,11 +445,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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user