Linux Integrity Measurement development
 help / color / mirror / Atom feed
From: Jarkko Sakkinen <jarkko@kernel.org>
To: Jaewon Yang <yong010301@gmail.com>
Cc: Peter Huewe <peterhuewe@gmx.de>, Jason Gunthorpe <jgg@ziepe.ca>,
	linux-integrity@vger.kernel.org, linux-kernel@vger.kernel.org,
	security@kernel.org
Subject: Re: [PATCH] tpm: Reject reads outside the response buffer
Date: Sat, 11 Jul 2026 20:08:02 +0300	[thread overview]
Message-ID: <alJ4cg_lWo1mdLl8@kernel.org> (raw)
In-Reply-To: <20260710090217.191289-1-yong010301@gmail.com>

On Fri, Jul 10, 2026 at 06:02:17PM +0900, Jaewon Yang wrote:
> 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.

I will choose to skip reading most of the text as already commit
message had zero relevant information.

Thus, NAK.

Please don't delegate the work for me that  you should doing i.e.
looking at your reproducer and describing the scenario/sequence
that would lead to infeasible consequence.


> 
>  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
> 

BR, Jarkko

  reply	other threads:[~2026-07-11 17:08 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-10  9:02 [PATCH] tpm: Reject reads outside the response buffer Jaewon Yang
2026-07-11 17:08 ` Jarkko Sakkinen [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=alJ4cg_lWo1mdLl8@kernel.org \
    --to=jarkko@kernel.org \
    --cc=jgg@ziepe.ca \
    --cc=linux-integrity@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=peterhuewe@gmx.de \
    --cc=security@kernel.org \
    --cc=yong010301@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox