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);
|
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);
|
return tpm_get_random(chip, data, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -370,6 +370,13 @@ int tpm_pm_suspend(struct device *dev)
|
|||||||
if (!chip)
|
if (!chip)
|
||||||
return -ENODEV;
|
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)
|
if (chip->flags & TPM_CHIP_FLAG_ALWAYS_POWERED)
|
||||||
goto suspended;
|
goto suspended;
|
||||||
|
|
||||||
@ -377,21 +384,19 @@ int tpm_pm_suspend(struct device *dev)
|
|||||||
!pm_suspend_via_firmware())
|
!pm_suspend_via_firmware())
|
||||||
goto suspended;
|
goto suspended;
|
||||||
|
|
||||||
rc = tpm_try_get_ops(chip);
|
if (chip->flags & TPM_CHIP_FLAG_TPM2) {
|
||||||
if (!rc) {
|
tpm2_end_auth_session(chip);
|
||||||
if (chip->flags & TPM_CHIP_FLAG_TPM2) {
|
tpm2_shutdown(chip, TPM2_SU_STATE);
|
||||||
tpm2_end_auth_session(chip);
|
goto suspended;
|
||||||
tpm2_shutdown(chip, TPM2_SU_STATE);
|
|
||||||
} else {
|
|
||||||
rc = tpm1_pm_suspend(chip, tpm_suspend_pcr);
|
|
||||||
}
|
|
||||||
|
|
||||||
tpm_put_ops(chip);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rc = tpm1_pm_suspend(chip, tpm_suspend_pcr);
|
||||||
|
|
||||||
suspended:
|
suspended:
|
||||||
chip->flags |= TPM_CHIP_FLAG_SUSPENDED;
|
chip->flags |= TPM_CHIP_FLAG_SUSPENDED;
|
||||||
|
tpm_put_ops(chip);
|
||||||
|
|
||||||
|
out:
|
||||||
if (rc)
|
if (rc)
|
||||||
dev_err(dev, "Ignoring error %d while suspending\n", rc);
|
dev_err(dev, "Ignoring error %d while suspending\n", rc);
|
||||||
return 0;
|
return 0;
|
||||||
@ -440,11 +445,18 @@ int tpm_get_random(struct tpm_chip *chip, u8 *out, size_t max)
|
|||||||
if (!chip)
|
if (!chip)
|
||||||
return -ENODEV;
|
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)
|
if (chip->flags & TPM_CHIP_FLAG_TPM2)
|
||||||
rc = tpm2_get_random(chip, out, max);
|
rc = tpm2_get_random(chip, out, max);
|
||||||
else
|
else
|
||||||
rc = tpm1_get_random(chip, out, max);
|
rc = tpm1_get_random(chip, out, max);
|
||||||
|
|
||||||
|
out:
|
||||||
tpm_put_ops(chip);
|
tpm_put_ops(chip);
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user