linux/drivers/char/tpm
Jaewon Yang f20d61c22b tpm: Make the TPM character devices non-seekable
The TPM character devices expose a sequential command/response
interface, but their open handlers leave FMODE_PREAD and FMODE_PWRITE
enabled.

After a command leaves a response pending, pread(fd, buf, 16, 0x1400)
passes 0x1400 as *off to tpm_common_read(). The transfer length is
bounded by response_length, but the offset is used unchecked when
forming data_buffer + *off. A sufficiently large offset therefore causes
an out-of-bounds heap read through copy_to_user() and, if the copy
succeeds, an out-of-bounds zero-write through the following memset().

Positional I/O does not provide coherent semantics for this interface.
An arbitrary pread offset cannot represent how much of a response has
been consumed sequentially. The write callback always stores a command
at the start of data_buffer, while pwrite() does not update file->f_pos
and can leave the sequential read cursor stale.

Call nonseekable_open() from both open handlers. This removes
FMODE_PREAD and FMODE_PWRITE, causing positional reads and writes to
fail with -ESPIPE before reaching the TPM callbacks, and explicitly
marks the files non-seekable. Normal read() and write() continue to use
the existing sequential f_pos cursor, leaving the response state machine
unchanged.

Tested on Linux 6.12 with KASAN and a swtpm TPM2 device:

 - sequential partial reads returned the complete response
 - pread() and preadv() with offset 0x1400 returned -ESPIPE
 - pwrite() and pwritev() with offset zero returned -ESPIPE
 - the pending response remained intact after the rejected operations
 - a subsequent normal command/response cycle completed normally
 - no KASAN report was produced.

Fixes: 9488585b21 ("tpm: add support for partial reads")
Link: https://lore.kernel.org/all/20260710090217.191289-1-yong010301@gmail.com/
Cc: stable@vger.kernel.org
Signed-off-by: Jaewon Yang <yong010301@gmail.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
2026-07-12 12:52:34 -07:00
..
eventlog tpm: fix event_size output in tpm1_binary_bios_measurements_show 2026-06-21 04:25:28 +03:00
st33zp24 tpm: st33zp24: Fix missing cleanup on get_burstcount() error 2026-02-03 02:36:32 +02:00
Kconfig tpm: Compare HMAC values in constant time 2025-10-10 08:21:45 +03:00
Makefile tpm: Add a driver for Loongson TPM device 2025-09-02 12:29:57 +01:00
tpm_atmel.c tpm: add bufsiz parameter in the .send callback 2025-07-23 02:23:18 +03:00
tpm_crb_ffa.c tpm: tpm_crb_ffa: revert defered_probed when tpm_crb_ffa is built-in 2026-06-21 04:25:28 +03:00
tpm_crb_ffa.h tpm_crb_ffa: Remove unused export 2025-07-23 02:23:18 +03:00
tpm_crb.c tpm_crb: Check ACPI_COMPANION() against NULL during probe 2026-06-21 04:25:28 +03:00
tpm_ftpm_tee.c tpm/tpm_ftpm_tee: Fix kdoc after function renames 2026-01-15 10:28:33 +01:00
tpm_ftpm_tee.h tpm/tpm_ftpm_tee: support TPM_CHIP_FLAG_SYNC 2025-07-23 02:23:18 +03:00
tpm_i2c_atmel.c tpm: i2c: atmel: fix block comment formatting 2026-04-21 18:54:28 +03:00
tpm_i2c_infineon.c tpm: tpm_i2c_infineon: Fix locality leak on get_burstcount() failure 2026-02-03 02:36:32 +02:00
tpm_i2c_nuvoton.c tpm: add bufsiz parameter in the .send callback 2025-07-23 02:23:18 +03:00
tpm_ibmvtpm.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
tpm_ibmvtpm.h tpm: ibmvtpm: Avoid error message when process gets signal while waiting 2021-08-23 19:55:42 +03:00
tpm_infineon.c tpm: add bufsiz parameter in the .send callback 2025-07-23 02:23:18 +03:00
tpm_loongson.c tpm: loongson: Add bufsiz parameter to tpm_loongson_send() 2025-09-25 12:45:03 +01:00
tpm_nsc.c tpm: add bufsiz parameter in the .send callback 2025-07-23 02:23:18 +03:00
tpm_ppi.c tpm: Prevent local DOS via tpm/tpm0/ppi/*operations 2025-10-10 08:21:45 +03:00
tpm_svsm.c tpm: svsm: constify tpm_chip_ops 2026-06-21 04:25:27 +03:00
tpm_tis_core.c tpm: tpm_tis: Add settle time for some TPMs 2026-06-21 04:25:28 +03:00
tpm_tis_core.h tpm: tpm_tis: Add settle time for some TPMs 2026-06-21 04:25:28 +03:00
tpm_tis_i2c_cr50.c char: tpm: cr50: Remove IRQF_ONESHOT 2026-02-01 17:37:15 +01:00
tpm_tis_i2c.c tpm: Drop explicit initialization of struct i2c_device_id::driver_data to 0 2024-09-17 18:56:37 +03:00
tpm_tis_spi_cr50.c char: tpm: cr50: Remove IRQF_ONESHOT 2026-02-01 17:37:15 +01:00
tpm_tis_spi_main.c tpm_tis_spi: add missing attpm20p SPI device ID entry 2024-07-01 15:50:02 +00:00
tpm_tis_spi.h tpm: Remove read16/read32/write32 calls from tpm_tis_phy_ops 2022-05-23 18:47:49 +03:00
tpm_tis_synquacer.c Get rid of 'remove_new' relic from platform driver struct 2024-12-01 15:12:43 -08:00
tpm_tis.c Get rid of 'remove_new' relic from platform driver struct 2024-12-01 15:12:43 -08:00
tpm_vtpm_proxy.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
tpm-buf.c char: tpm: tpm-buf: Add sanity check fallback in read helpers 2025-05-15 04:47:14 +03:00
tpm-chip.c tpm: Use kfree_sensitive() to free auth session in tpm_dev_release() 2026-04-21 18:54:28 +03:00
tpm-dev-common.c tpm: add WQ_PERCPU to alloc_workqueue users 2025-12-03 22:55:28 +02:00
tpm-dev.c tpm: Make the TPM character devices non-seekable 2026-07-12 12:52:34 -07:00
tpm-dev.h tpm: Handle negative priv->response_len in tpm_common_read() 2020-01-08 18:11:09 +02:00
tpm-interface.c tpm: Remove tpm_find_get_ops 2025-12-03 22:55:28 +02:00
tpm-sysfs.c tpm: add the null key name as a sysfs export 2024-05-09 22:30:52 +03:00
tpm.h kernel.h: drop hex.h and update all hex.h users 2026-01-20 19:44:19 -08:00
tpm1-cmd.c tpm: Cap the number of PCR banks 2025-12-03 22:55:28 +02:00
tpm2-cmd.c tpm: restore timeout for key creation commands 2026-06-21 04:25:28 +03:00
tpm2-sessions.c tpm: tpm2-sessions: wait for async KPP completion in tpm_buf_append_salt 2026-06-21 04:25:28 +03:00
tpm2-space.c move asm/unaligned.h to linux/unaligned.h 2024-10-02 17:23:23 -04:00
tpmrm-dev.c tpm: Make the TPM character devices non-seekable 2026-07-12 12:52:34 -07:00
xen-tpmfront.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00