CVE-2026-45871
Description
In the Linux kernel, the following vulnerability has been resolved:
tpm: st33zp24: Fix missing cleanup on get_burstcount() error
get_burstcount() can return -EBUSY on timeout. When this happens, st33zp24_send() returns directly without releasing the locality acquired earlier.
Use goto out_err to ensure proper cleanup when get_burstcount() fails.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Missing cleanup in Linux kernel TPM driver st33zp24 when get_burstcount() fails can lead to resource leak.
Vulnerability
The vulnerability is in the Linux kernel's TPM driver for STMicroelectronics ST33ZP24 (st33zp24). In the st33zp24_send() function, after acquiring a locality, the code calls get_burstcount(). If get_burstcount() returns an error (e.g., -EBUSY on timeout), the function returns directly without releasing the previously acquired locality. This missing cleanup affects all kernel versions containing this code path. The fix was applied in commit a51cff9be046 [1].
Exploitation
An attacker would need to trigger a timeout in get_burstcount(), which could be achieved by manipulating the TPM interface or causing a denial-of-service condition on the TPM bus. No special privileges are required beyond access to the TPM device. The attacker does not need to be local; if the TPM is accessible from user space (e.g., through /dev/tpm0), a user-space program can trigger the bug.
Impact
The impact is a resource leak: the locality is not released, which can lead to exhaustion of TPM localities, potentially causing denial of service for other TPM operations. In some configurations, this could also prevent the TPM from being used by other processes, leading to system instability. No data confidentiality or integrity is directly compromised.
Mitigation
The fix is included in the Linux kernel commit a51cff9be046 [1], which was merged into the stable kernel tree. Users should update to a kernel version containing this commit. If patching is not immediately possible, a workaround is to avoid operations that could cause get_burstcount() to time out, though this is not a reliable mitigation. The vulnerability is not listed in CISA's Known Exploited Vulnerabilities catalog as of the publication date.
AI Insight generated on May 27, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
2Patches
167687133509cftpm: st33zp24: Fix missing cleanup on get_burstcount() error
1 file changed · +4 −3
drivers/char/tpm/st33zp24/st33zp24.c+4 −3 modifieddiff --git a/drivers/char/tpm/st33zp24/st33zp24.c b/drivers/char/tpm/st33zp24/st33zp24.c index 4ec10ab5e5766e..33ee4fe6937962 100644 --- a/drivers/char/tpm/st33zp24/st33zp24.c +++ b/drivers/char/tpm/st33zp24/st33zp24.c @@ -381,8 +381,10 @@ static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf, for (i = 0; i < len - 1;) { burstcnt = get_burstcount(chip); - if (burstcnt < 0) - return burstcnt; + if (burstcnt < 0) { + ret = burstcnt; + goto out_err; + } size = min_t(int, len - i - 1, burstcnt); ret = tpm_dev->ops->send(tpm_dev->phy_id, TPM_DATA_FIFO, buf + i, size); -- cgit 1.3-korg
1256c6dc96d1tpm: st33zp24: Fix missing cleanup on get_burstcount() error
1 file changed · +4 −3
drivers/char/tpm/st33zp24/st33zp24.c+4 −3 modifieddiff --git a/drivers/char/tpm/st33zp24/st33zp24.c b/drivers/char/tpm/st33zp24/st33zp24.c index 15b393e92c8eca..71cc97f394b510 100644 --- a/drivers/char/tpm/st33zp24/st33zp24.c +++ b/drivers/char/tpm/st33zp24/st33zp24.c @@ -327,8 +327,10 @@ static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf, for (i = 0; i < len - 1;) { burstcnt = get_burstcount(chip); - if (burstcnt < 0) - return burstcnt; + if (burstcnt < 0) { + ret = burstcnt; + goto out_err; + } size = min_t(int, len - i - 1, burstcnt); ret = tpm_dev->ops->send(tpm_dev->phy_id, TPM_DATA_FIFO, buf + i, size); -- cgit 1.3-korg
cc09d55f519etpm: st33zp24: Fix missing cleanup on get_burstcount() error
1 file changed · +4 −3
drivers/char/tpm/st33zp24/st33zp24.c+4 −3 modifieddiff --git a/drivers/char/tpm/st33zp24/st33zp24.c b/drivers/char/tpm/st33zp24/st33zp24.c index c0771980bc2ff1..06caf53a42ee57 100644 --- a/drivers/char/tpm/st33zp24/st33zp24.c +++ b/drivers/char/tpm/st33zp24/st33zp24.c @@ -328,8 +328,10 @@ static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf, for (i = 0; i < len - 1;) { burstcnt = get_burstcount(chip); - if (burstcnt < 0) - return burstcnt; + if (burstcnt < 0) { + ret = burstcnt; + goto out_err; + } size = min_t(int, len - i - 1, burstcnt); ret = tpm_dev->ops->send(tpm_dev->phy_id, TPM_DATA_FIFO, buf + i, size); -- cgit 1.3-korg
ec15eb67fe9dtpm: st33zp24: Fix missing cleanup on get_burstcount() error
1 file changed · +4 −3
drivers/char/tpm/st33zp24/st33zp24.c+4 −3 modifieddiff --git a/drivers/char/tpm/st33zp24/st33zp24.c b/drivers/char/tpm/st33zp24/st33zp24.c index 2ed7815e4899b7..e2b7451ea7ccd3 100644 --- a/drivers/char/tpm/st33zp24/st33zp24.c +++ b/drivers/char/tpm/st33zp24/st33zp24.c @@ -328,8 +328,10 @@ static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf, for (i = 0; i < len - 1;) { burstcnt = get_burstcount(chip); - if (burstcnt < 0) - return burstcnt; + if (burstcnt < 0) { + ret = burstcnt; + goto out_err; + } size = min_t(int, len - i - 1, burstcnt); ret = tpm_dev->ops->send(tpm_dev->phy_id, TPM_DATA_FIFO, buf + i, size); -- cgit 1.3-korg
3e91b44c93adtpm: st33zp24: Fix missing cleanup on get_burstcount() error
1 file changed · +4 −3
drivers/char/tpm/st33zp24/st33zp24.c+4 −3 modifieddiff --git a/drivers/char/tpm/st33zp24/st33zp24.c b/drivers/char/tpm/st33zp24/st33zp24.c index 2ed7815e4899b7..e2b7451ea7ccd3 100644 --- a/drivers/char/tpm/st33zp24/st33zp24.c +++ b/drivers/char/tpm/st33zp24/st33zp24.c @@ -328,8 +328,10 @@ static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf, for (i = 0; i < len - 1;) { burstcnt = get_burstcount(chip); - if (burstcnt < 0) - return burstcnt; + if (burstcnt < 0) { + ret = burstcnt; + goto out_err; + } size = min_t(int, len - i - 1, burstcnt); ret = tpm_dev->ops->send(tpm_dev->phy_id, TPM_DATA_FIFO, buf + i, size); -- cgit 1.3-korg
4fffb77d35d0tpm: st33zp24: Fix missing cleanup on get_burstcount() error
1 file changed · +4 −3
drivers/char/tpm/st33zp24/st33zp24.c+4 −3 modifieddiff --git a/drivers/char/tpm/st33zp24/st33zp24.c b/drivers/char/tpm/st33zp24/st33zp24.c index 2ed7815e4899b7..e2b7451ea7ccd3 100644 --- a/drivers/char/tpm/st33zp24/st33zp24.c +++ b/drivers/char/tpm/st33zp24/st33zp24.c @@ -328,8 +328,10 @@ static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf, for (i = 0; i < len - 1;) { burstcnt = get_burstcount(chip); - if (burstcnt < 0) - return burstcnt; + if (burstcnt < 0) { + ret = burstcnt; + goto out_err; + } size = min_t(int, len - i - 1, burstcnt); ret = tpm_dev->ops->send(tpm_dev->phy_id, TPM_DATA_FIFO, buf + i, size); -- cgit 1.3-korg
a51cff9be046tpm: st33zp24: Fix missing cleanup on get_burstcount() error
1 file changed · +4 −3
drivers/char/tpm/st33zp24/st33zp24.c+4 −3 modifieddiff --git a/drivers/char/tpm/st33zp24/st33zp24.c b/drivers/char/tpm/st33zp24/st33zp24.c index a5b554cd477861..f78c61f4163d57 100644 --- a/drivers/char/tpm/st33zp24/st33zp24.c +++ b/drivers/char/tpm/st33zp24/st33zp24.c @@ -328,8 +328,10 @@ static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf, for (i = 0; i < len - 1;) { burstcnt = get_burstcount(chip); - if (burstcnt < 0) - return burstcnt; + if (burstcnt < 0) { + ret = burstcnt; + goto out_err; + } size = min_t(int, len - i - 1, burstcnt); ret = tpm_dev->ops->send(tpm_dev->phy_id, TPM_DATA_FIFO, buf + i, size); -- cgit 1.3-korg
e0ce3da82341tpm: st33zp24: Fix missing cleanup on get_burstcount() error
1 file changed · +4 −3
drivers/char/tpm/st33zp24/st33zp24.c+4 −3 modifieddiff --git a/drivers/char/tpm/st33zp24/st33zp24.c b/drivers/char/tpm/st33zp24/st33zp24.c index 4ec10ab5e5766e..33ee4fe6937962 100644 --- a/drivers/char/tpm/st33zp24/st33zp24.c +++ b/drivers/char/tpm/st33zp24/st33zp24.c @@ -381,8 +381,10 @@ static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf, for (i = 0; i < len - 1;) { burstcnt = get_burstcount(chip); - if (burstcnt < 0) - return burstcnt; + if (burstcnt < 0) { + ret = burstcnt; + goto out_err; + } size = min_t(int, len - i - 1, burstcnt); ret = tpm_dev->ops->send(tpm_dev->phy_id, TPM_DATA_FIFO, buf + i, size); -- cgit 1.3-korg
e0ce3da82341tpm: st33zp24: Fix missing cleanup on get_burstcount() error
1 file changed · +4 −3
drivers/char/tpm/st33zp24/st33zp24.c+4 −3 modifieddiff --git a/drivers/char/tpm/st33zp24/st33zp24.c b/drivers/char/tpm/st33zp24/st33zp24.c index 4ec10ab5e5766e..33ee4fe6937962 100644 --- a/drivers/char/tpm/st33zp24/st33zp24.c +++ b/drivers/char/tpm/st33zp24/st33zp24.c @@ -381,8 +381,10 @@ static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf, for (i = 0; i < len - 1;) { burstcnt = get_burstcount(chip); - if (burstcnt < 0) - return burstcnt; + if (burstcnt < 0) { + ret = burstcnt; + goto out_err; + } size = min_t(int, len - i - 1, burstcnt); ret = tpm_dev->ops->send(tpm_dev->phy_id, TPM_DATA_FIFO, buf + i, size); -- cgit 1.3-korg
a51cff9be046tpm: st33zp24: Fix missing cleanup on get_burstcount() error
1 file changed · +4 −3
drivers/char/tpm/st33zp24/st33zp24.c+4 −3 modifieddiff --git a/drivers/char/tpm/st33zp24/st33zp24.c b/drivers/char/tpm/st33zp24/st33zp24.c index a5b554cd477861..f78c61f4163d57 100644 --- a/drivers/char/tpm/st33zp24/st33zp24.c +++ b/drivers/char/tpm/st33zp24/st33zp24.c @@ -328,8 +328,10 @@ static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf, for (i = 0; i < len - 1;) { burstcnt = get_burstcount(chip); - if (burstcnt < 0) - return burstcnt; + if (burstcnt < 0) { + ret = burstcnt; + goto out_err; + } size = min_t(int, len - i - 1, burstcnt); ret = tpm_dev->ops->send(tpm_dev->phy_id, TPM_DATA_FIFO, buf + i, size); -- cgit 1.3-korg
cc09d55f519etpm: st33zp24: Fix missing cleanup on get_burstcount() error
1 file changed · +4 −3
drivers/char/tpm/st33zp24/st33zp24.c+4 −3 modifieddiff --git a/drivers/char/tpm/st33zp24/st33zp24.c b/drivers/char/tpm/st33zp24/st33zp24.c index c0771980bc2ff1..06caf53a42ee57 100644 --- a/drivers/char/tpm/st33zp24/st33zp24.c +++ b/drivers/char/tpm/st33zp24/st33zp24.c @@ -328,8 +328,10 @@ static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf, for (i = 0; i < len - 1;) { burstcnt = get_burstcount(chip); - if (burstcnt < 0) - return burstcnt; + if (burstcnt < 0) { + ret = burstcnt; + goto out_err; + } size = min_t(int, len - i - 1, burstcnt); ret = tpm_dev->ops->send(tpm_dev->phy_id, TPM_DATA_FIFO, buf + i, size); -- cgit 1.3-korg
3e91b44c93adtpm: st33zp24: Fix missing cleanup on get_burstcount() error
1 file changed · +4 −3
drivers/char/tpm/st33zp24/st33zp24.c+4 −3 modifieddiff --git a/drivers/char/tpm/st33zp24/st33zp24.c b/drivers/char/tpm/st33zp24/st33zp24.c index 2ed7815e4899b7..e2b7451ea7ccd3 100644 --- a/drivers/char/tpm/st33zp24/st33zp24.c +++ b/drivers/char/tpm/st33zp24/st33zp24.c @@ -328,8 +328,10 @@ static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf, for (i = 0; i < len - 1;) { burstcnt = get_burstcount(chip); - if (burstcnt < 0) - return burstcnt; + if (burstcnt < 0) { + ret = burstcnt; + goto out_err; + } size = min_t(int, len - i - 1, burstcnt); ret = tpm_dev->ops->send(tpm_dev->phy_id, TPM_DATA_FIFO, buf + i, size); -- cgit 1.3-korg
ec15eb67fe9dtpm: st33zp24: Fix missing cleanup on get_burstcount() error
1 file changed · +4 −3
drivers/char/tpm/st33zp24/st33zp24.c+4 −3 modifieddiff --git a/drivers/char/tpm/st33zp24/st33zp24.c b/drivers/char/tpm/st33zp24/st33zp24.c index 2ed7815e4899b7..e2b7451ea7ccd3 100644 --- a/drivers/char/tpm/st33zp24/st33zp24.c +++ b/drivers/char/tpm/st33zp24/st33zp24.c @@ -328,8 +328,10 @@ static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf, for (i = 0; i < len - 1;) { burstcnt = get_burstcount(chip); - if (burstcnt < 0) - return burstcnt; + if (burstcnt < 0) { + ret = burstcnt; + goto out_err; + } size = min_t(int, len - i - 1, burstcnt); ret = tpm_dev->ops->send(tpm_dev->phy_id, TPM_DATA_FIFO, buf + i, size); -- cgit 1.3-korg
4fffb77d35d0tpm: st33zp24: Fix missing cleanup on get_burstcount() error
1 file changed · +4 −3
drivers/char/tpm/st33zp24/st33zp24.c+4 −3 modifieddiff --git a/drivers/char/tpm/st33zp24/st33zp24.c b/drivers/char/tpm/st33zp24/st33zp24.c index 2ed7815e4899b7..e2b7451ea7ccd3 100644 --- a/drivers/char/tpm/st33zp24/st33zp24.c +++ b/drivers/char/tpm/st33zp24/st33zp24.c @@ -328,8 +328,10 @@ static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf, for (i = 0; i < len - 1;) { burstcnt = get_burstcount(chip); - if (burstcnt < 0) - return burstcnt; + if (burstcnt < 0) { + ret = burstcnt; + goto out_err; + } size = min_t(int, len - i - 1, burstcnt); ret = tpm_dev->ops->send(tpm_dev->phy_id, TPM_DATA_FIFO, buf + i, size); -- cgit 1.3-korg
1256c6dc96d1tpm: st33zp24: Fix missing cleanup on get_burstcount() error
1 file changed · +4 −3
drivers/char/tpm/st33zp24/st33zp24.c+4 −3 modifieddiff --git a/drivers/char/tpm/st33zp24/st33zp24.c b/drivers/char/tpm/st33zp24/st33zp24.c index 15b393e92c8eca..71cc97f394b510 100644 --- a/drivers/char/tpm/st33zp24/st33zp24.c +++ b/drivers/char/tpm/st33zp24/st33zp24.c @@ -327,8 +327,10 @@ static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf, for (i = 0; i < len - 1;) { burstcnt = get_burstcount(chip); - if (burstcnt < 0) - return burstcnt; + if (burstcnt < 0) { + ret = burstcnt; + goto out_err; + } size = min_t(int, len - i - 1, burstcnt); ret = tpm_dev->ops->send(tpm_dev->phy_id, TPM_DATA_FIFO, buf + i, size); -- cgit 1.3-korg
7687133509cftpm: st33zp24: Fix missing cleanup on get_burstcount() error
1 file changed · +4 −3
drivers/char/tpm/st33zp24/st33zp24.c+4 −3 modifieddiff --git a/drivers/char/tpm/st33zp24/st33zp24.c b/drivers/char/tpm/st33zp24/st33zp24.c index 4ec10ab5e5766e..33ee4fe6937962 100644 --- a/drivers/char/tpm/st33zp24/st33zp24.c +++ b/drivers/char/tpm/st33zp24/st33zp24.c @@ -381,8 +381,10 @@ static int st33zp24_send(struct tpm_chip *chip, unsigned char *buf, for (i = 0; i < len - 1;) { burstcnt = get_burstcount(chip); - if (burstcnt < 0) - return burstcnt; + if (burstcnt < 0) { + ret = burstcnt; + goto out_err; + } size = min_t(int, len - i - 1, burstcnt); ret = tpm_dev->ops->send(tpm_dev->phy_id, TPM_DATA_FIFO, buf + i, size); -- cgit 1.3-korg
Vulnerability mechanics
Root cause
"Missing cleanup path in st33zp24_send() when get_burstcount() fails, causing the TPM locality to remain locked."
Attack vector
An attacker who can cause the TPM to become unresponsive or slow enough that `get_burstcount()` times out can trigger this bug. When `get_burstcount()` returns -EBUSY, `st33zp24_send()` previously returned immediately without releasing the TPM locality acquired earlier. This leaves the locality locked, preventing the TPM from servicing subsequent commands from the kernel or other consumers. The attack requires the ability to induce a timeout condition on the TPM bus, which could be achieved through physical access or by exploiting a separate TPM communication issue.
Affected code
The vulnerability is in the `st33zp24_send()` function in `drivers/char/tpm/st33zp24/st33zp24.c` [patch_id=2661853]. The function acquires a TPM locality early in its execution, then enters a loop calling `get_burstcount()`. If `get_burstcount()` returns a negative value (e.g., -EBUSY on timeout), the old code returned that error directly without releasing the locality.
What the fix does
The patch changes the error handling in `st33zp24_send()` so that when `get_burstcount()` returns a negative value, the error code is stored in `ret` and execution jumps to the `out_err` label instead of returning immediately [patch_id=2661853]. The `out_err` label is the existing cleanup path that releases the TPM locality. This ensures that the locality is always released before returning from the function, preventing resource leaks.
Preconditions
- inputThe attacker must be able to cause get_burstcount() to time out (return -EBUSY), e.g., by making the TPM unresponsive.
- configThe system must be using the st33zp24 TPM driver.
Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
8- git.kernel.org/stable/c/1256c6dc96d1e687e6e9b63088156ed07411b00cnvd
- git.kernel.org/stable/c/3e91b44c93ad2871f89fc2a98c5e4fe6ca5db3d9nvd
- git.kernel.org/stable/c/4fffb77d35d038f146e6192da583dbe4971d869envd
- git.kernel.org/stable/c/7687133509cf66ced120b667fefd21f80bf17993nvd
- git.kernel.org/stable/c/a51cff9be046e13e1c1b2fe45d5c48b582ec9b8cnvd
- git.kernel.org/stable/c/cc09d55f519e15355de343264a22ac6682b8305envd
- git.kernel.org/stable/c/e0ce3da82341fcd6194175f1837946b2a894c625nvd
- git.kernel.org/stable/c/ec15eb67fe9df87981b4829b901ec254273ca483nvd
News mentions
0No linked articles in our index yet.