Skip to content

Commit 571b6bb

Browse files
dabros-jangregkh
authored andcommitted
char: tpm: Protect tpm_pm_suspend with locks
commit 23393c6 upstream. Currently tpm transactions are executed unconditionally in tpm_pm_suspend() function, which may lead to races with other tpm accessors in the system. Specifically, the hw_random tpm driver makes use of tpm_get_random(), and this function is called in a loop from a kthread, which means it's not frozen alongside userspace, and so can race with the work done during system suspend: tpm tpm0: tpm_transmit: tpm_recv: error -52 tpm tpm0: invalid TPM_STS.x 0xff, dumping stack for forensics CPU: 0 PID: 1 Comm: init Not tainted 6.1.0-rc5+ #135 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.0-20220807_005459-localhost 04/01/2014 Call Trace: tpm_tis_status.cold+0x19/0x20 tpm_transmit+0x13b/0x390 tpm_transmit_cmd+0x20/0x80 tpm1_pm_suspend+0xa6/0x110 tpm_pm_suspend+0x53/0x80 __pnp_bus_suspend+0x35/0xe0 __device_suspend+0x10f/0x350 Fix this by calling tpm_try_get_ops(), which itself is a wrapper around tpm_chip_start(), but takes the appropriate mutex. Signed-off-by: Jan Dabros <[email protected]> Reported-by: Vlastimil Babka <[email protected]> Tested-by: Jason A. Donenfeld <[email protected]> Tested-by: Vlastimil Babka <[email protected]> Link: https://lore.kernel.org/all/[email protected]/ Cc: [email protected] Fixes: e891db1 ("tpm: turn on TPM on suspend for TPM 1.x") [Jason: reworked commit message, added metadata] Signed-off-by: Jason A. Donenfeld <[email protected]> Reviewed-by: Jarkko Sakkinen <[email protected]> Signed-off-by: Linus Torvalds <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent f39891c commit 571b6bb

File tree

1 file changed

+3
-2
lines changed

1 file changed

+3
-2
lines changed

drivers/char/tpm/tpm-interface.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -401,13 +401,14 @@ int tpm_pm_suspend(struct device *dev)
401401
!pm_suspend_via_firmware())
402402
goto suspended;
403403

404-
if (!tpm_chip_start(chip)) {
404+
rc = tpm_try_get_ops(chip);
405+
if (!rc) {
405406
if (chip->flags & TPM_CHIP_FLAG_TPM2)
406407
tpm2_shutdown(chip, TPM2_SU_STATE);
407408
else
408409
rc = tpm1_pm_suspend(chip, tpm_suspend_pcr);
409410

410-
tpm_chip_stop(chip);
411+
tpm_put_ops(chip);
411412
}
412413

413414
suspended:

0 commit comments

Comments
 (0)