| Age | Commit message (Collapse) | Author |
|
The TPM2_CAP_PCRS response is external input. tpm2_get_pcr_allocation()
adds every active selection to allocated_banks, while
tpm_sysfs_add_device() has one group slot per distinct hash algorithm.
Eight duplicate selections can therefore write past chip->groups[].
The TPM protocol does not allow a hash algorithm to appear twice in
this capability response. Treat a duplicate as a broken TPM and return
-EIO so the chip is not enabled, instead of silently dropping the
extra selection.
Assisted-by: LLM
Signed-off-by: Yuqi Xu <xuyuqiabc@gmail.com>
Reviewed-by: Ren Wei <weir@nebusec.ai>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/9d27c4513a3c6fc32f9574ba192cd3bfcb2bac98.1790568982.git.xuyuqiabc@gmail.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
Replace the deprecated SIMPLE_DEV_PM_OPS with DEFINE_SIMPLE_DEV_PM_OPS
and wrap the struct assignment with pm_sleep_ptr(). The old code keeps
a completely empty dev_pm_ops structure -- all callbacks are NULL --
as dead code in the object file when CONFIG_PM_SLEEP=n, because
SET_SYSTEM_SLEEP_PM_OPS() expands to nothing while __maybe_unused on
the struct only silences the warning without removing the struct.
Switching to DEFINE_SIMPLE_DEV_PM_OPS() lets pm_sleep_ptr() eliminate
the callback references at compile time, and wrapping the struct
assignment with pm_sleep_ptr() drops the entire structure when
CONFIG_PM_SLEEP is disabled, instead of retaining an empty one.
Signed-off-by: Li Jun <lijun01@kylinos.cn>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/20260909082459.796628-1-lijun01@kylinos.cn
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
Replace the manually defined dev_pm_ops structure with the
SIMPLE_DEV_PM_OPS macro to simplify the power management code.
This macro automatically handles CONFIG_PM_SLEEP configuration,
generating the same suspend/resume callbacks while reducing
boilerplate code.Add the value of 'thaw,freeze,poweroff,restore'.
Signed-off-by: Li Jun <lijun01@kylinos.cn>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/20260819083547.2703228-1-lijun01@kylinos.cn
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
The common TPM Device Tree binding already documents resets and
reset-gpios, but the TIS I2C driver never requests a reset control.
As a result, an I2C TPM held in reset by board wiring remains
inaccessible and the first register access during probe fails.
Request the optional reset control and deassert it before
communicating with the TPM. This keeps existing boards without a reset
line unchanged while allowing platforms using resets or reset-gpios to
release the TPM before probe continues.
Tested on a Variscite DART-MX95 with an ST33KTPM2XI2C TPM using
reset-gpios.
Signed-off-by: Stefano Radaelli <stefano.r@variscite.com>
Link: https://lore.kernel.org/r/20260917124211.136221-1-stefano.r@variscite.com
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
The comment above the wmb() in tpm_pm_resume() states that the barrier
guarantees TPM_CHIP_FLAG_SUSPENDED is written last, so that hwrng does
not activate before the chip has been fully resumed. It cannot do so:
it is placed after the store that clears the flag, and therefore does
not order the preceding resume work before that store. It also has
nothing to pair with, as tpm_try_get_ops() contains no matching read
barrier.
Drop the barrier along with the comment rather than leave a no-op
behind. Should such ordering turn out to be needed, it would require
paired barriers or locking.
Link: https://lore.kernel.org/all/a62fc816-259a-4d28-a265-e425bc17ed50@gmail.com/
Signed-off-by: Richard Lyu <richard.lyu@suse.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/20260910024430.40418-1-richard.lyu@suse.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
Some TPM implementations, particularly fTPM using the CRB interface,
require the TPM to transition through idle and ready states for each
command rather than once per session.
The current implementation calls cmd_ready once during tpm_chip_start()
and go_idle once during tpm_chip_stop(). For fTPM, when multiple commands
are sent without per-command idle transitions, subsequent commands timeout
as the TPM is waiting for the transition.
Fix this by calling cmd_ready before each command and go_idle on all exit
paths in tpm_try_transmit(). For TPM implementations that don't require
per-command transitions, the callbacks return immediately based on the
start method.
Remove the now-redundant per-session calls from tpm_chip_start() and
tpm_chip_stop() along with their helpers.
This resolves timeout errors during TPM initialization on systems where
BIOS has already performed TPM startup.
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/20260901213723.3017371-1-mario.limonciello@amd.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
POSIX requires that a read() with a count of zero returns zero and
has no other effects. tpm_common_read() treats such a call as a
consumed response: it marks the pending response as read and drops
it, so the response can never be retrieved; subsequent reads return
zero and the next write() is allowed to overwrite the response
buffer, silently breaking the command/response pairing of the TPM
character devices.
Return early when the caller passes a zero count, leaving any
pending response untouched for the next read. A zero-length read
will not report a deferred asynchronous error; POSIX permits read()
to skip error detection for a zero count.
Cc: stable@vger.kernel.org
Fixes: 9488585b21be ("tpm: add support for partial reads")
Assisted-by: GLM-5.3
Signed-off-by: Pei Xiao <xiaopei01@kylinos.cn>
Link: https://lore.kernel.org/r/3f15140ab3c26e98b49d6aceaaa826585d56960b.1791015549.git.xiaopei01@kylinos.cn
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
tpm_nsc_remove() is called explicitly from cleanup_nsc() and also
runs as the platform device release callback on the final
platform_device_put(), so the cleanup executes twice on module
exit; the second invocation operates on a chip that has already
been freed by the devm cleanup, and the I/O region is released
twice.
Overwriting the release callback installed by
platform_device_alloc() also keeps platform_device_release() from
running, leaking the platform object allocation.
Leave the default release callback in place; the explicit call in
cleanup_nsc() remains the single cleanup point.
Cc: stable@vger.kernel.org
Fixes: 570302a31149 ("[PATCH] tpm: move nsc driver off pci_dev")
Assisted-by: GLM-5.3
Signed-off-by: Pei Xiao <xiaopei01@kylinos.cn>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/a6155310e6772f708b47291cc959e02c05b90eb7.1791015549.git.xiaopei01@kylinos.cn
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
tpm_nsc_remove() is used as the release callback of the hand-created
platform device and dereferences the chip drvdata unconditionally.
If init fails before tpmm_chip_alloc() (e.g. request_region() cannot
claim the ports), the error path drops the last device reference and
the release callback runs with chip == NULL, crashing module init.
Return early when the chip has not been created yet.
Cc: stable@vger.kernel.org
Fixes: afb5abc262e9 ("tpm: two-phase chip management functions")
Assisted-by: GLM-5.3
Signed-off-by: Pei Xiao <xiaopei01@kylinos.cn>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/d5f0b38d6d6c17c01519c879d26448dbae388b0e.1791015549.git.xiaopei01@kylinos.cn
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
tpm2_probe() reads the protocol version from the response tag and is
documented to return -errno on failure, but it always returns 0. A
transport error (tpm_transmit_cmd() < 0) is thus swallowed together with
the intentionally ignored TPM response code, leaving TPM_CHIP_FLAG_TPM2
unset. A transient bus failure on the first command then misdetects a
TPM 2.0 as a 1.2 and the probe fails on the TPM 1.2 path:
tpm_tis_i2c 0-002e: 1.2 TPM (device-id 0x1C, rev-id 22)
tpm tpm0: A TPM error (-62) occurred attempting to determine the timeouts
Return the transport error instead; rc >= 0 still means a valid header was
received and the TPM's own response code is still ignored.
Fixes: 94e266ba1fa3 ("tpm: migrate tpm2_probe() to use struct tpm_buf")
Cc: stable@vger.kernel.org
Signed-off-by: Alexander Sverdlin <alexander.sverdlin@siemens.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/20261001060114.1582092-1-alexander.sverdlin@siemens.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
The null key name check exists to protect against TPM reset attacks, so
a mismatch should stop the device from serving further requests.
Currently it does not disable the chip when it finds a mismatch.
The mismatch is logged:
tpm tpm0: null key integrity check failed
but the chip keeps serving commands:
/ # tpm2_getcap -c properties-fixed
TPM_PT_FAMILY_INDICATOR:
as UINT32: 0x08322e3000
as string: "2.0"
...
tpm2_load_null() where the null key name check is run sets the chip as
disabled only if the rc is non zero. When the mismatch is seen, rc is
zero at that point and it returns success. The other issue is that the
caller expects the null key handle to be populated when the function
returns 0 which it does here without writing the handle and proceeds
assuming the null key handle is valid.
During the test, I noticed that tpm2_start_auth_session() uses the
uninitialized stack value as the key handle since tpm2_load_null()
returns 0 despite the integrity failure and proceeds with
TPM2_CC_START_AUTH_SESS with this value as salt key handle.
Set rc to -ENODEV on the mismatch. The error path then disables the chip
and returns the correct code to the caller.
Tested in QEMU with swtpm and CONFIG_TCG_TPM2_HMAC=y by making
TPM2_CC_CONTEXT_LOAD fail with TPM2_RC_INTEGRITY and changing the name
of the re-created null key. The chip is now disabled on the mismatch.
Fixes: cc7d8594342a ("tpm: Rollback tpm2_load_null()")
Fixes: 423893fcbe7e ("tpm: Disable TPM on tpm2_create_primary() failure")
Cc: stable@vger.kernel.org # v6.12+
Assisted-by: LLM
Signed-off-by: Surendran Kanagaraj <surenkj@amazon.com>
Link: https://lore.kernel.org/r/20260918000731.48657-1-surenkj@amazon.com
Reviewed-by: Gunnar Kudrjavets <gunnarku@amazon.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
When the response carries the TPM2_ST_SESSIONS tag, tpm2_get_random()
skips the 4-byte parameter size field before locating the random data,
but the bounds check still validates the response length against
TPM_HEADER_SIZE. A truncated response can pass the check and make
memcpy() read up to 4 bytes past the response end, so stale buffer
contents end up in the caller's random bytes.
Fix this by checking the response length against 'offset', which
already includes the skipped parameter size field.
Cc: stable@vger.kernel.org # v6.12+
Fixes: 1b6d7f9eb150 ("tpm: add session encryption protection to tpm2_get_random()")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260902074839.417419-1-yijiangshan%40kylinos.cn
Signed-off-by: Jiangshan Yi <yijiangshan@kylinos.cn>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/20260903035837.219284-1-yijiangshan@kylinos.cn
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
When tpm_buf_fill_hmac_session() fails in tpm2_get_random(), the error
path returns without calling tpm2_end_auth_session(), leaking the auth
session. All other error paths in the function handle this correctly.
Fixes: 3d9e043dab0a ("tpm-buf: Memory-safe allocations")
Cc: stable@vger.kernel.orga # v6.12+
Signed-off-by: Jiangshan Yi <yijiangshan@kylinos.cn>
Link: https://lore.kernel.org/r/20260902074839.417419-1-yijiangshan@kylinos.cn
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
struct tpm_buf now uses an embedded flexible array for data, which is
6 bytes shorter than TPM_BUFSIZE due to the struct header. But
tpm_transmit_cmd() still passes PAGE_SIZE to tpm_transmit(), and after
clamping to TPM_BUFSIZE in tpm_try_transmit(), chip->ops->recv() can
write past the end of data[] by 6 bytes.
Pass buf->capacity to tpm_transmit() instead.
Fixes: 3d9e043dab0a ("tpm-buf: Memory-safe allocations")
Signed-off-by: Jiangshan Yi <yijiangshan@kylinos.cn>
Link: https://lore.kernel.org/r/20260901062850.379870-1-yijiangshan@kylinos.cn
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
Extract all the functions and definitions for TPM buffer handling
and separate them into their own header.
Signed-off-by: Ross Philipson <ross.philipson@gmail.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
Decouple kzalloc from buffer creation, so that a managed allocation can be
used:
struct tpm_buf *buf __free(kfree) buf = kzalloc(TPM_BUFSIZE,
GFP_KERNEL);
if (!buf)
return -ENOMEM;
tpm_buf_init(buf, TPM_BUFSIZE);
Alternatively, other allocations are also possible (static data, stack,
etc) for example:
u8 buf_data[512];
struct tpm_buf *buf = (struct tpm_buf *)buf_data;
tpm_buf_init(buf, sizeof(buf_data));
This is achieved by embedding buffer's header inside the allocated blob,
instead of having an outer wrapper.
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@opinsys.com>
Tested-by: Srish Srinivasan <ssrish@linux.ibm.com>
Message-ID: <20260522013555.1063716-1-jarkko@kernel.org>
Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
|
|
Remove the TPM driver chip parameter from the function
tpm_buf_append_handle(). The chip parameter is only for error logging
which can be done with other facilities like WARN().
Message-ID: <20260125192526.782202-11-jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@opinsys.com>
Signed-off-by: Ross Philipson <ross.philipson@gmail.com>
|
|
Merge TPM_BUF_BOUNDARY_ERROR and TPM_BUF_OVERFLOW flags into
the TPM_BUF_INVALID flag, as their behavior is identical (the only
difference being the associated log messages).
Message-ID: <20260125192526.782202-11-jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@opinsys.com>
Reviewed-by: Jonathan McDowell <noodles@meta.com>
Signed-off-by: Ross Philipson <ross.philipson@gmail.com>
|
|
These are definitions for TPM 2.0 interface and interactions with
the platform as defined in the TCG specification:
These definitions are located here in a separate file to avoid conflicts
with vendor specific TIS/FIFO definition (e.g. STMicroelectronics,
Infineon Technologies, etc). This allows the TCG defined TIS/FIFO
interface to be in a public header while the former chip specific
implementations contain their own definitions. TPM 1.x family chips
that adhere to the TCG specifications use the TIS/FIFO interface as
defined here.
TCG PC Client Platform TPM Profile (PTP) Specification
- https://trustedcomputinggroup.org/resource/pc-client-platform-tpm-profile-ptp-specification/
Co-developed-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Co-developed-by: Alec Brown <alec.r.brown@oracle.com>
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
Signed-off-by: Ross Philipson <ross.philipson@gmail.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
These are top level definitions shared by both TPM 1 and 2
family chips. This includes core definitions like TPM localities,
common crypto algorithm IDs, and the base TPM command header.
Co-developed-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Co-developed-by: Alec Brown <alec.r.brown@oracle.com>
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
Signed-off-by: Ross Philipson <ross.philipson@gmail.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
Gather all the TPM2 definitions and structures in the internal header
file drivers/char/tpm/tpm.h into the command header, including:
- Command codes, return codes and definitions from the public and
internal tpm.h files.
- Structures defined in numerous TPM driver C modules.
The definitions moved to these files correspond to the TCG specification
for TPM 2 family:
TPM 2.0 Library
- https://trustedcomputinggroup.org/resource/tpm-library-specification/
Co-developed-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Co-developed-by: Alec Brown <alec.r.brown@oracle.com>
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
Signed-off-by: Ross Philipson <ross.philipson@gmail.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
Gather all the TPM1 definitions and structures from the internal header
file drivers/char/tpm/tpm.h into the command header. In addition, bring
in the single RNG structure from tpm1-cmd.c.
The definitions moved to these files correspond to the TCG specification
for TPM 1 family:
TPM 1.2 Main Specification
- https://trustedcomputinggroup.org/resource/tpm-main-specification/
Co-developed-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Co-developed-by: Alec Brown <alec.r.brown@oracle.com>
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
Signed-off-by: Ross Philipson <ross.philipson@gmail.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
Consolidate TPM1 constants in tpm_command.h and remove duplicate
constants from tpm1-cmd.c.
Co-developed-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com>
Co-developed-by: Alec Brown <alec.r.brown@oracle.com>
Signed-off-by: Alec Brown <alec.r.brown@oracle.com>
Signed-off-by: Ross Philipson <ross.philipson@gmail.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
check_locality() treats every nonzero transport return as success. SPI
errors remain negative, while the I2C path can convert a negative write
error through its byte-sized status variable. Either result is nonzero
even though the TPM_ACCESS byte can remain unwritten, so indeterminate
ACTIVE_LOCALITY and VALID bits can falsely report an active locality.
Require recv() to return exactly the requested byte before examining
TPM_ACCESS. Transport errors and short reads now report an inactive
locality, while successful reads retain the existing behavior.
This issue was found by a static analysis checker and confirmed by manual
source review.
Fixes: 251a7b08213a ("TPM: STMicroelectronics ST33 I2C KERNEL 3.x")
Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
Link: https://lore.kernel.org/r/20260813153032.3951878-2-ruoyuw560@gmail.com
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
st33zp24_status() ignores the result of the transport read and returns
data even when no byte was received. The I2C transport, for example,
skips i2c_master_recv() when the register-select write is short or fails,
leaving data uninitialized. The resulting stack value can be interpreted
as TPM_STS flags and let status checks complete spuriously.
The status callback cannot propagate a transport error. Return zero
unless recv() reports exactly one byte. With no status bits set, callers
retry or take their existing timeout or error path instead of acting on
an invalid status value.
This issue was found by a static analysis checker and confirmed by manual
source review.
Fixes: 251a7b08213a ("TPM: STMicroelectronics ST33 I2C KERNEL 3.x")
Signed-off-by: Ruoyu Wang <ruoyuw560@gmail.com>
Link: https://lore.kernel.org/r/20260813153032.3951878-1-ruoyuw560@gmail.com
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
if no define CONFIG_TCG_TIS_SPI_CR50 in config,
the add of tpm_tis_spi_resume is null, this cause the tpm chip to
fail to resume.
Signed-off-by: Li Jun <lijun01@kylinos.cn>
Link: https://lore.kernel.org/r/20260812100914.3540149-1-lijun01@kylinos.cn
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
tpm_atmel probes for the chip at fixed x86 Super-I/O ports (0x4e) with
inb()/outb(), so it only works on x86. TCG_ATMEL nevertheless depends
only on HAS_IOPORT_MAP/HAS_IOPORT, which arm and arm64 also satisfy.
There the probe is useless, and on platforms whose unbacked I/O access
faults it oopses in init_atmel() at boot (e.g. arm/versatile):
Unable to handle kernel paging request at virtual address fee0004e
PC is at init_atmel+0x34/0x244
TCG_NSC and TCG_TIS already "depends on X86" (commit 2f592f2a7d74 ("TPM:
NSC and TIS drivers X86 dependency fix")); TCG_ATMEL was missed. Add the
same dependency.
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/20260712183234.23125-1-kmehltretter@gmail.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
Since commit 55b48e23f5c4 ("genirq/devres: Add error handling in
devm_request_*_irq()"), devm_request_irq() automatically logs
detailed error messages on failure. Remove the now-redundant
driver-specific dev_err() calls.
Signed-off-by: Pan Chuang <panchuang@vivo.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/20260710105318.376496-3-panchuang@vivo.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
i2c_nuvoton_wait_for_stat() enables the IRQ before waiting for the
interrupt handler to report a status change. If the wait times out, or is
interrupted before the handler runs, the function returns without
balancing the enable_irq() call.
Disable the IRQ before leaving the failed wait path. Also preserve an
interrupted wait's original error code instead of converting it to
-ETIMEDOUT inside the helper.
Cc: stable@vger.kernel.org # v5.10+
Fixes: 4c336e4b1556 ("tpm: Add support for the Nuvoton NPCT501 I2C TPM")
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/20260626091653.54929-1-mhun512@gmail.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
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: 9488585b21be ("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>
|
|
Commit 186d124f07da ("tpm_eventlog.c: fix binary_bios_measurements")
split the output to write the endian-converted event header first and
then the variable-length event data.
However, the split was at sizeof(struct tcpa_event) - 1, even though
event_data was a zero-length array, and later a flexible array member,
both of which already excluded the event data.
Therefore, the current code writes the first three bytes of event_size
from the endian-converted header and then the last byte from the raw
header, which can emit a corrupted event_size on PPC64, where
do_endian_conversion() maps to be32_to_cpu().
Split one byte later to write the full endian-converted header first,
followed by the variable-length event->event_data.
Fixes: 186d124f07da ("tpm_eventlog.c: fix binary_bios_measurements")
Cc: stable@vger.kernel.org # v5.10+
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
commit 746d9e9f62a6 ("tpm: tpm_crb_ffa: try to probe tpm_crb_ffa when it's built-in")
probe tpm_crb_ffa forcefully when it's built-in to integrate with IMA.
However, IMA now provides the IMA_INIT_LATE_SYNC build option, which
initialises IMA at the late_initcall_sync level, so this change is no
longer required.
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
Link: https://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux.git/commit/?h=for-next/ffa/updates&id=cc7e8f21b9f0c229d68cf19a837cba82b5ac2d87 [0]
Link: https://git.kernel.org/pub/scm/linux/kernel/git/sudeep.holla/linux.git/commit/?h=for-next/ffa/updates&id=e659fc8e537c7a21d5d693d6f30d8852f2fa8d91 [1]
Link: https://lore.kernel.org/r/20260605144325.434436-5-yeoreum.yun@arm.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
tpm_buf_append_salt() in drivers/char/tpm/tpm2-sessions.c calls
crypto_kpp_generate_public_key() and crypto_kpp_compute_shared_secret()
without installing a completion callback, discards both return values,
and immediately frees the kpp_request via kpp_request_free(). When the
resolved ecdh-nist-p256 KPP backend is asynchronous (atmel-ecc, HPRE,
keembay-ocs), either operation returns -EINPROGRESS and the deferred
completion worker dereferences the freed request.
The path fires automatically from the hwrng_fillfn kernel thread via
tpm_get_random -> tpm2_get_random -> tpm2_start_auth_session ->
tpm_buf_append_salt on every entropy poll, without any userland action.
Install crypto_req_done as the completion callback, wrap both KPP
operations in crypto_wait_req(), and propagate errors to the caller.
The wait is a no-op for synchronous backends.
Fixes: 1085b8276bb4 ("tpm: Add the rest of the session HMAC API")
Cc: stable@vger.kernel.org # v6.10+
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Assisted-by: Claude:claude-opus-4-7
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
Some TPMs fail to grant locality when requested immediately after being
relinquished. In this case, the TPM_ACCESS_REQUEST_USE bit of the
TPM_ACCESS register is cleared immediately without setting
TPM_ACCESS_ACTIVE_LOCALITY.
This issue can be seen at boot since tpm_chip_start, called right
after locality is relinquished, will fail. This causes the probe to
fail:
tpm_tis MSFT0101:00: probe with driver tpm_tis failed with error -1
This occurs on some older Dell Latitudes. For the Nuvoton TPM used in
these machines, add a delay after locality is relinquished.
Signed-off-by: Jim Broadus <jbroadus@gmail.com>
Link: https://lore.kernel.org/r/20260526232245.5409-3-jbroadus@gmail.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
The entire 32 bit did_vid is read from the device, but only the 16 bit
vendor id portion was stored in the tpm_tis_data structure. Storing the
entire value allows the device id to be used to handle quirks. Printing
the vid and did in the error case also helps identify problem devices.
Signed-off-by: Jim Broadus <jbroadus@gmail.com>
Link: https://lore.kernel.org/r/20260526232245.5409-2-jbroadus@gmail.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
Every platform driver can be forced to match a device that doesn't match
its list of device IDs because of device_match_driver_override(), so
platform drivers that rely on the existence of a device's ACPI companion
object need to verify its presence.
Accordingly, add a requisite ACPI_COMPANION() check against NULL to the
tpm_crb driver.
Fixes: 48fe2cddc85c ("tpm_crb: Convert ACPI driver to a platform one")
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Link: https://lore.kernel.org/r/2848144.mvXUDI8C0e@rafael.j.wysocki
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
wait_event_interruptible_timeout() evaluates its condition after setting
the current task state to TASK_INTERRUPTIBLE.
With CONFIG_DEBUG_ATOMIC_SLEEP this triggers a warning when the IRQ wait
path is used:
tpm_tis_status()
tpm_tis_spi_read_bytes()
tpm_tis_spi_transfer_full()
spi_bus_lock()
mutex_lock()
Address this with the following measures:
1. Call wait_tpm_stat_cond() only while tasking is running.
2. Use wait_woken() to wait for changes.
Cc: stable@vger.kernel.org # v4.19+
Cc: Linus Walleij <linusw@kernel.org>
Reported-by: Stefan Wahren <wahrenst@gmx.net>
Closes: https://lore.kernel.org/linux-integrity/6964bec7-3dbb-453b-89ef-9b990217a8b9@gmx.net/
Fixes: 1a339b658d9d ("tpm_tis_spi: Pass the SPI IRQ down to the driver")
Reviewed-by: Linus Walleij <linusw@kernel.org>
Tested-by: Stefan Wahren <wahrenst@gmx.net>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
tpm_buf_append_name() supports callers passing a pre-computed name
for handles. When name is non-NULL, the code skips the
tpm2_read_public() path but leaves name_size_alg uninitialized
before it is used as the memcpy size argument.
No current in-tree caller passes a non-NULL name, but future use
cases such as name caching would exercise this path. Initialize
name_size_alg by calling name_size() on the caller-provided name,
sharing the error check and assignment with the existing
tpm2_read_public() path. This prevents unmasking a latent bug when
the non-NULL name path is eventually used.
Assisted-by: Kiro:claude-opus-4.6
Reviewed-by: Justinien Bouron <jbouron@amazon.com>
Reviewed-by: Muhammad Hammad Ijaz <mhijaz@amazon.com>
Signed-off-by: Gunnar Kudrjavets <gunnarku@amazon.com>
Link: https://lore.kernel.org/r/20260510171152.4607-1-gunnarku@amazon.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
Commit 207696b17f38 ("tpm: use a map for tpm2_calc_ordinal_duration()")
inadvertently reduced the timeout for TPM2 key creation commands
(`CREATE_PRIMARY`, `CREATE`, `CREATE_LOADED`) from 300 seconds to 30
seconds.
This causes intermittent timeout failures, with several failures observed
across hundreds of test runs on some Intel platforms using Infineon
SLB9670 and SLB9672 TPM modules. Restore the timeout to 300 seconds to
avoid spurious failures.
Cc: stable@vger.kernel.org # v6.18+
Fixes: 207696b17f38 ("tpm: use a map for tpm2_calc_ordinal_duration()")
Co-developed-by: Lili Li <lili.li@intel.com>
Signed-off-by: Lili Li <lili.li@intel.com>
Signed-off-by: Baoli Zhang <baoli.zhang@linux.intel.com>
Link: https://lore.kernel.org/r/20260421005021.13765-1-baoli.zhang@linux.intel.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
Constify the SVSM vTPM ops. It is statically initialized and never
written to, so let's store it in .rodata.
Every other tpm_class_ops instance in drivers/char/tpm/ is already
const.
Signed-off-by: David Windsor <dwindsor@gmail.com>
Reviewed-by: Stefano Garzarella <sgarzare@redhat.com>
Link: https://lore.kernel.org/r/20260505202738.145800-1-dwindsor@gmail.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
tpm_tis_send_main() will attempt to retry sending data TPM_RETRY times.
Currently, if those retries are exhausted, the driver will attempt to
call execute. The TPM will be in the wrong state, leading to the
operation simply timing out.
Instead, if there is still an error after retries are exhausted, return
that error immediately.
Cc: stable@vger.kernel.org # v6.6+
Fixes: 280db21e153d8 ("tpm_tis: Resend command to recover from data transfer errors")
Signed-off-by: Jacqueline Wong <jacqwong@google.com>
Signed-off-by: Jordan Hand <jhand@google.com>
Link: https://lore.kernel.org/r/20260415160006.2275325-3-jacqwong@google.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
Add logging to more easily determine reason for transmit failure
Cc: stable@vger.kernel.org # v6.6+
Fixes: 280db21e153d8 ("tpm_tis: Resend command to recover from data transfer errors")
Signed-off-by: Jacqueline Wong <jacqwong@google.com>
Signed-off-by: Jordan Hand <jhand@google.com>
Link: https://lore.kernel.org/r/20260415160006.2275325-2-jacqwong@google.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
tpm_dev_release() uses plain kfree() to free chip->auth, which contains
sensitive cryptographic material including HMAC session keys, nonces,
and passphrase data (struct tpm2_auth).
Every other code path that frees this structure uses kfree_sensitive()
to zero the memory before releasing it: both tpm2_end_auth_session()
and tpm_buf_check_hmac_response() do so. The tpm_dev_release() path
is the only one that does not, leaving key material in freed slab
memory until it is eventually overwritten.
Use kfree_sensitive() for consistency with the rest of the driver and
to ensure session keys are scrubbed during device teardown.
Cc: stable@vger.kernel.org # v6.10+
Fixes: 699e3efd6c64 ("tpm: Add HMAC session start and end functions")
Signed-off-by: Gunnar Kudrjavets <gunnarku@amazon.com>
Reviewed-by: Justinien Bouron <jbouron@amazon.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
tpm2_read_public() calls tpm_buf_init() but fails to call
tpm_buf_destroy() on two exit paths, leaking a page allocation:
1. When name_size() returns an error (unrecognized hash algorithm),
the function returns directly without destroying the buffer.
2. On the success path, the buffer is never destroyed before
returning.
All other error paths in the function correctly call
tpm_buf_destroy() before returning.
Fix both by adding the missing tpm_buf_destroy() calls.
Cc: stable@vger.kernel.org # v6.19+
Fixes: bda1cbf73c6e ("tpm2-sessions: Fix tpm2_read_public range checks")
Signed-off-by: Gunnar Kudrjavets <gunnarku@amazon.com>
Reviewed-by: Justinien Bouron <jbouron@amazon.com>
Reviewed-by: Paul Menzel <pmenzel@molgen.mpg.de>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
When tpm_buf_fill_hmac_session() fails inside the do-while loop in
tpm2_get_random(), the function returns directly after destroying the
buffer, without ending the auth session via tpm2_end_auth_session().
This leaks the TPM auth session resource. All other error paths within
the loop correctly reach the 'out' label which calls both
tpm_buf_destroy() and tpm2_end_auth_session().
Fix this by replacing the early return with a goto to the existing 'out'
label, which already handles both cleanup operations. The redundant
tpm_buf_destroy() call is removed since 'out' takes care of it.
Cc: stable@vger.kernel.org # v6.19+
Fixes: 6e9722e9a7bf ("tpm2-sessions: Fix out of range indexing in name_size")
Signed-off-by: Gunnar Kudrjavets <gunnarku@amazon.com>
Reviewed-by: Justinien Bouron <jbouron@amazon.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
Multiple block comments in tpm_i2c_atmel.c placed the closing '*/' on the
same line as the comment text. This violates the kernel's preferred
comment style, which requires the closing delimiter to appear on its
line.
Fix the formatting to improve readability and resolve checkpatch
warnings.
Signed-off-by: Ethan Luna <trunixcodes@zohomail.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
In all cases in which a struct acpi_driver is used for binding a driver
to an ACPI device object, a corresponding platform device is created by
the ACPI core and that device is regarded as a proper representation of
underlying hardware. Accordingly, a struct platform_driver should be
used by driver code to bind to that device. There are multiple reasons
why drivers should not bind directly to ACPI device objects [1].
Overall, it is better to bind drivers to platform devices than to their
ACPI companions, so convert the tpm_crb ACPI driver to a platform one.
While this is not expected to alter functionality, it changes sysfs
layout and so it will be visible to user space.
Link: https://lore.kernel.org/all/2396510.ElGaqSPkdT@rafael.j.wysocki/ [1]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
File-scope 'tcpci_pm_ops' is not used outside of this unit and is not
modified anywhere, so make it static const to silence sparse warning:
tcpci.c:1002:1: warning: symbol 'tcpci_pm_ops' was not declared. Should it be static?
Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
|
|
This was done entirely with mindless brute force, using
git grep -l '\<k[vmz]*alloc_objs*(.*, GFP_KERNEL)' |
xargs sed -i 's/\(alloc_objs*(.*\), GFP_KERNEL)/\1)/'
to convert the new alloc_obj() users that had a simple GFP_KERNEL
argument to just drop that argument.
Note that due to the extreme simplicity of the scripting, any slightly
more complex cases spread over multiple lines would not be triggered:
they definitely exist, but this covers the vast bulk of the cases, and
the resulting diff is also then easier to check automatically.
For the same reason the 'flex' versions will be done as a separate
conversion.
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
|
|
This is the result of running the Coccinelle script from
scripts/coccinelle/api/kmalloc_objs.cocci. The script is designed to
avoid scalar types (which need careful case-by-case checking), and
instead replace kmalloc-family calls that allocate struct or union
object instances:
Single allocations: kmalloc(sizeof(TYPE), ...)
are replaced with: kmalloc_obj(TYPE, ...)
Array allocations: kmalloc_array(COUNT, sizeof(TYPE), ...)
are replaced with: kmalloc_objs(TYPE, COUNT, ...)
Flex array allocations: kmalloc(struct_size(PTR, FAM, COUNT), ...)
are replaced with: kmalloc_flex(*PTR, FAM, COUNT, ...)
(where TYPE may also be *VAR)
The resulting allocations no longer return "void *", instead returning
"TYPE *".
Signed-off-by: Kees Cook <kees@kernel.org>
|