All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] tpm: Reject reads outside the response buffer
@ 2026-07-10  9:02 Jaewon Yang
  2026-07-11 17:08 ` Jarkko Sakkinen
  0 siblings, 1 reply; 8+ messages in thread
From: Jaewon Yang @ 2026-07-10  9:02 UTC (permalink / raw)
  To: Peter Huewe, Jarkko Sakkinen
  Cc: Jason Gunthorpe, linux-integrity, linux-kernel, security

tpm_common_read() clamps the transfer length to priv->response_length but
does not validate the file offset (*off) before using it to index the
fixed TPM_BUFSIZE-byte priv->data_buffer:

	ret_size = min_t(ssize_t, size, priv->response_length);
	copy_to_user(buf, priv->data_buffer + *off, ret_size);
	memset(priv->data_buffer + *off, 0, ret_size);

Sequential read() keeps *off in range, but the fops use the legacy .read
callback and neither tpm_open() nor tpmrm_open() calls nonseekable_open(),
so FMODE_PREAD stays set and pread(2) passes an arbitrary offset straight
into *off. An out-of-range offset then accesses memory beyond data_buffer,
causing an out-of-bounds read through copy_to_user() and, when the copy
succeeds, an out-of-bounds zero-write through memset().

Reject any read whose offset and length leave the response buffer.

Fixes: 9488585b21be ("tpm: add support for partial reads")
Cc: stable@vger.kernel.org
Signed-off-by: Jaewon Yang <yong010301@gmail.com>
---
Notes for reviewers (not part of the commit):

Reproduced on a KASAN 6.12 build with a swtpm TPM2 device. After a command
leaves a response pending, pread(fd, buf, 16, 0x1400) triggers two
slab-out-of-bounds reports, one for the copy_to_user() read and one for the
memset() write; on that x86-64 build the faulting access was 962 bytes past
a 4344-byte struct tpmrm_priv served from kmalloc-8k. With this patch,
out-of-range preads (offset past the buffer, at the end, or an in-range
offset whose length crosses the end) return -EINVAL with no KASAN report,
while sequential partial reads still return the full response and a normal
read after a rejected pread still works.

Reaching it needs a process that can open the TPM device and send a command.
Access depends on the device-node permissions; the upstream tpm2-tss udev
rules set tpmrm devices to mode 0660 with group tss. My reproduction ran as
root, so I have not shown non-root reach on a specific distribution or built
a privilege-escalation chain.

I searched public archives on 2026-07-10 and found no matching report, which
does not rule out a private, very recent, or unindexed one. Found through
AI-assisted source review; the code path and reproduction were verified by
hand. A reproducer and full logs are available on request.

 drivers/char/tpm/tpm-dev-common.c | 10 ++++++++++
 1 file changed, 10 insertions(+)

diff --git a/drivers/char/tpm/tpm-dev-common.c b/drivers/char/tpm/tpm-dev-common.c
index f942c0c8e..dbf049028 100644
--- a/drivers/char/tpm/tpm-dev-common.c
+++ b/drivers/char/tpm/tpm-dev-common.c
@@ -145,6 +145,16 @@ ssize_t tpm_common_read(struct file *file, char __user *buf,
 			goto out;
 		}
 
+		/*
+		 * Reject reads whose offset and length fall outside the fixed
+		 * response buffer.
+		 */
+		if (*off < 0 || *off >= TPM_BUFSIZE ||
+		    ret_size > TPM_BUFSIZE - *off) {
+			ret_size = -EINVAL;
+			goto out;
+		}
+
 		rc = copy_to_user(buf, priv->data_buffer + *off, ret_size);
 		if (rc) {
 			memset(priv->data_buffer, 0, TPM_BUFSIZE);
-- 
2.43.0


^ permalink raw reply related	[flat|nested] 8+ messages in thread

end of thread, other threads:[~2026-07-18 18:20 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-10  9:02 [PATCH] tpm: Reject reads outside the response buffer Jaewon Yang
2026-07-11 17:08 ` Jarkko Sakkinen
2026-07-11 18:58   ` Linus Torvalds
2026-07-12 17:11     ` [PATCH v2] tpm: Make the TPM character devices non-seekable Jaewon Yang
2026-07-12 19:54       ` Linus Torvalds
2026-07-18 18:13       ` Jarkko Sakkinen
2026-07-18 18:20         ` Jarkko Sakkinen
2026-07-18 18:17     ` [PATCH] tpm: Reject reads outside the response buffer Jarkko Sakkinen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.