git: a0da653aaeae - main - tpm20: Initialize common state before testing TIS interrupts
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 03 Sep 2026 03:53:25 UTC
The branch main has been updated by kbowling:
URL: https://cgit.FreeBSD.org/src/commit/?id=a0da653aaeae313479f2ab37d0faca483f530fa6
commit a0da653aaeae313479f2ab37d0faca483f530fa6
Author: Kevin Bowling <kbowling@FreeBSD.org>
AuthorDate: 2026-08-26 10:51:58 +0000
Commit: Kevin Bowling <kbowling@FreeBSD.org>
CommitDate: 2026-09-03 03:53:02 +0000
tpm20: Initialize common state before testing TIS interrupts
The TIS attach path tested its interrupt by transmitting GetRandom
before tpm20_init() allocated the internal command buffer. A TPM2 FIFO
device with a usable IRQ could therefore dereference a null
internal_priv.
Initialize the common TPM2 state before running the interrupt test.
Make common cleanup safe for partially initialized devices and leave
cleanup to the attachment after tpm20_init() fails, avoiding duplicate
release of the lock, command buffer, and random-source state.
Clear the IRQ resource pointer after releasing it when interrupt handler
setup fails so the later polling-mode detach does not release it twice.
Free the internal command allocation through its object pointer rather
than relying on its embedded buffer being the first structure member.
Reviewed by: kevans
MFC after: 2 weeks
Sponsored by: BBOX.io
Differential Revision: https://reviews.freebsd.org/D59196
---
sys/dev/tpm/tpm20.c | 19 ++++++++++++++-----
sys/dev/tpm/tpm20.h | 1 +
sys/dev/tpm/tpm_tis_core.c | 14 +++++++++-----
3 files changed, 24 insertions(+), 10 deletions(-)
diff --git a/sys/dev/tpm/tpm20.c b/sys/dev/tpm/tpm20.c
index 22189d112656..20521b2ed361 100644
--- a/sys/dev/tpm/tpm20.c
+++ b/sys/dev/tpm/tpm20.c
@@ -157,7 +157,7 @@ tpm20_priv_dtor(void *data)
{
struct tpm_priv *priv = data;
- free(priv->buf, M_TPM20);
+ free(priv, M_TPM20);
}
int
@@ -209,7 +209,7 @@ tpm20_init(struct tpm_sc *sc)
args.mda_si_drv1 = sc;
result = make_dev_s(&args, &sc->sc_cdev, TPM_CDEV_NAME);
if (result != 0)
- tpm20_release(sc);
+ return (result);
#if defined TPM_HARVEST || defined RANDOM_ENABLE_TPM
random_source_register(&random_tpm);
@@ -217,6 +217,7 @@ tpm20_init(struct tpm_sc *sc)
tpm20_harvest, sc);
taskqueue_enqueue_timeout(taskqueue_thread, &sc->harvest_task, 0);
#endif
+ sc->common_initialized = true;
return (result);
@@ -226,16 +227,24 @@ void
tpm20_release(struct tpm_sc *sc)
{
+ if (!sc->common_initialized)
+ goto out;
#if defined TPM_HARVEST || defined RANDOM_ENABLE_TPM
if (device_is_attached(sc->dev))
taskqueue_drain_timeout(taskqueue_thread, &sc->harvest_task);
random_source_deregister(&random_tpm);
#endif
-
- tpm20_priv_dtor(sc->internal_priv);
+ sc->common_initialized = false;
+out:
+ if (sc->internal_priv != NULL) {
+ tpm20_priv_dtor(sc->internal_priv);
+ sc->internal_priv = NULL;
+ }
sx_destroy(&sc->dev_lock);
- if (sc->sc_cdev != NULL)
+ if (sc->sc_cdev != NULL) {
destroy_dev(sc->sc_cdev);
+ sc->sc_cdev = NULL;
+ }
}
int
diff --git a/sys/dev/tpm/tpm20.h b/sys/dev/tpm/tpm20.h
index a004bdea9e06..7570812219b9 100644
--- a/sys/dev/tpm/tpm20.h
+++ b/sys/dev/tpm/tpm20.h
@@ -128,6 +128,7 @@ struct tpm_sc {
void *intr_cookie;
int intr_type; /* Current event type */
bool interrupts;
+ bool common_initialized;
struct tpm_priv *internal_priv;
diff --git a/sys/dev/tpm/tpm_tis_core.c b/sys/dev/tpm/tpm_tis_core.c
index 95e914fa570b..15370e648f1e 100644
--- a/sys/dev/tpm/tpm_tis_core.c
+++ b/sys/dev/tpm/tpm_tis_core.c
@@ -120,17 +120,21 @@ tpmtis_attach(device_t dev)
result = bus_setup_intr(dev, sc->irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
NULL, tpmtis_intr_handler, sc, &sc->intr_cookie);
if (result != 0) {
- bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq_res);
+ if (bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid,
+ sc->irq_res) == 0)
+ sc->irq_res = NULL;
goto skip_irq;
}
- tpmtis_setup_intr(sc);
-
skip_irq:
result = tpm20_init(sc);
- if (result != 0)
+ if (result != 0) {
tpmtis_detach(dev);
+ return (result);
+ }
+ if (sc->intr_cookie != NULL)
+ tpmtis_setup_intr(sc);
- return (result);
+ return (0);
}
static int