Linux kernel -stable discussions
 help / color / mirror / Atom feed
From: Sasha Levin <sashal@kernel.org>
To: patches@lists.linux.dev, stable@vger.kernel.org
Cc: Yeoreum Yun <yeoreum.yun@arm.com>,
	Mimi Zohar <zohar@linux.ibm.com>,
	Sudeep Holla <sudeep.holla@arm.com>,
	Jarkko Sakkinen <jarkko@kernel.org>,
	Sasha Levin <sashal@kernel.org>,
	peterhuewe@gmx.de, linux-integrity@vger.kernel.org
Subject: [PATCH AUTOSEL 6.15 08/34] tpm: tpm_crb_ffa: try to probe tpm_crb_ffa when it's built-in
Date: Sun,  3 Aug 2025 17:18:10 -0400	[thread overview]
Message-ID: <20250803211836.3546094-8-sashal@kernel.org> (raw)
In-Reply-To: <20250803211836.3546094-1-sashal@kernel.org>

From: Yeoreum Yun <yeoreum.yun@arm.com>

[ Upstream commit 746d9e9f62a6e8ba0eba2b83fc61cfe7fa8797ce ]

To generate the boot_aggregate log in the IMA subsystem using TPM PCR
values, the TPM driver must be built as built-in and must be probed
before the IMA subsystem is initialized.

However, when the TPM device operates over the FF-A protocol using the
CRB interface, probing fails and returns -EPROBE_DEFER if the
tpm_crb_ffa device — an FF-A device that provides the communication
interface to the tpm_crb driver — has not yet been probed.

This issue occurs because both crb_acpi_driver_init() and
tpm_crb_ffa_driver_init() are registered with device_initcall.  As a
result, crb_acpi_driver_init() may be invoked before
tpm_crb_ffa_driver_init(), which is responsible for probing the
tpm_crb_ffa device.

When this happens, IMA fails to detect the TPM device and logs the
following message:

  | ima: No TPM chip found, activating TPM-bypass!

Consequently, it cannot generate the boot_aggregate log with the PCR
values provided by the TPM.

To resolve this issue, the tpm_crb_ffa_init() function explicitly
attempts to probe the tpm_crb_ffa by register tpm_crb_ffa driver so that
when tpm_crb_ffa device is created before tpm_crb_ffa_init(), probe the
tpm_crb_ffa device in tpm_crb_ffa_init() to finish probe the TPM device
completely.

This ensures that the TPM device using CRB over FF-A can be successfully
probed, even if crb_acpi_driver_init() is called first.

[ jarkko: reformatted some of the paragraphs because they were going past
  the 75 character boundary. ]

Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
Reviewed-by: Mimi Zohar <zohar@linux.ibm.com>
Reviewed-by: Sudeep Holla <sudeep.holla@arm.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---

LLM Generated explanations, may be completely bogus:

**Backport Status: YES**

This commit should be backported to stable kernel trees for the
following reasons:

1. **Fixes a functional bug affecting users**: The commit addresses a
   race condition where IMA (Integrity Measurement Architecture) fails
   to detect TPM devices that use CRB over FF-A, resulting in the
   message "ima: No TPM chip found, activating TPM-bypass!" This
   prevents IMA from generating boot_aggregate logs with TPM PCR values,
   which is a critical security feature.

2. **Small and contained fix**: The change is minimal and focused:
   - Adds a static forward declaration of `tpm_crb_ffa_driver`
   - Modifies `tpm_crb_ffa_init()` to explicitly register the FFA driver
     when built-in
   - Adds conditional compilation guards around `module_ffa_driver()`

3. **No architectural changes**: The fix doesn't introduce new features
   or change the architecture. It simply ensures proper driver
   registration ordering when the driver is built-in.

4. **Clear root cause**: The issue occurs because both
   `crb_acpi_driver_init()` and `tpm_crb_ffa_driver_init()` are
   registered with `device_initcall`, leading to unpredictable
   initialization order. When `crb_acpi_driver_init()` runs first, it
   calls `tpm_crb_ffa_init()` which returns `-ENOENT` because the FFA
   driver hasn't been registered yet.

5. **Security implications**: TPM is a critical security component, and
   IMA's inability to use TPM measurements compromises system integrity
   attestation. This fix ensures security features work as intended.

6. **Minimal risk**: The changes only affect the initialization path
   when `CONFIG_TCG_ARM_CRB_FFA` is built-in (not as a module). The fix:
   - Only executes when `!IS_MODULE(CONFIG_TCG_ARM_CRB_FFA)`
   - Preserves existing error handling
   - Doesn't change the module case behavior

7. **Well-reviewed**: The commit has been reviewed by multiple
   maintainers including Mimi Zohar (IMA maintainer), Sudeep Holla (ARM
   FF-A maintainer), and Jarkko Sakkinen (TPM maintainer).

The fix is important for ARM systems using FF-A to communicate with TPM
devices, ensuring that security features like IMA work correctly when
TPM drivers are built into the kernel.

 drivers/char/tpm/tpm_crb_ffa.c | 19 ++++++++++++++++---
 1 file changed, 16 insertions(+), 3 deletions(-)

diff --git a/drivers/char/tpm/tpm_crb_ffa.c b/drivers/char/tpm/tpm_crb_ffa.c
index 3169a87a56b6..430b99c04124 100644
--- a/drivers/char/tpm/tpm_crb_ffa.c
+++ b/drivers/char/tpm/tpm_crb_ffa.c
@@ -109,6 +109,7 @@ struct tpm_crb_ffa {
 };
 
 static struct tpm_crb_ffa *tpm_crb_ffa;
+static struct ffa_driver tpm_crb_ffa_driver;
 
 static int tpm_crb_ffa_to_linux_errno(int errno)
 {
@@ -162,13 +163,23 @@ static int tpm_crb_ffa_to_linux_errno(int errno)
  */
 int tpm_crb_ffa_init(void)
 {
+	int ret = 0;
+
+	if (!IS_MODULE(CONFIG_TCG_ARM_CRB_FFA)) {
+		ret = ffa_register(&tpm_crb_ffa_driver);
+		if (ret) {
+			tpm_crb_ffa = ERR_PTR(-ENODEV);
+			return ret;
+		}
+	}
+
 	if (!tpm_crb_ffa)
-		return -ENOENT;
+		ret = -ENOENT;
 
 	if (IS_ERR_VALUE(tpm_crb_ffa))
-		return -ENODEV;
+		ret = -ENODEV;
 
-	return 0;
+	return ret;
 }
 EXPORT_SYMBOL_GPL(tpm_crb_ffa_init);
 
@@ -341,7 +352,9 @@ static struct ffa_driver tpm_crb_ffa_driver = {
 	.id_table = tpm_crb_ffa_device_id,
 };
 
+#ifdef MODULE
 module_ffa_driver(tpm_crb_ffa_driver);
+#endif
 
 MODULE_AUTHOR("Arm");
 MODULE_DESCRIPTION("TPM CRB FFA driver");
-- 
2.39.5


  parent reply	other threads:[~2025-08-03 21:18 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-08-03 21:18 [PATCH AUTOSEL 6.15 01/34] hfs: fix general protection fault in hfs_find_init() Sasha Levin
2025-08-03 21:18 ` [PATCH AUTOSEL 6.15 02/34] hfs: fix slab-out-of-bounds in hfs_bnode_read() Sasha Levin
2025-08-03 21:18 ` [PATCH AUTOSEL 6.15 03/34] hfsplus: fix slab-out-of-bounds in hfsplus_bnode_read() Sasha Levin
2025-08-03 21:18 ` [PATCH AUTOSEL 6.15 04/34] hfsplus: fix slab-out-of-bounds read in hfsplus_uni2asc() Sasha Levin
2025-08-03 21:18 ` [PATCH AUTOSEL 6.15 05/34] hfsplus: don't use BUG_ON() in hfsplus_create_attributes_file() Sasha Levin
2025-08-03 21:18 ` [PATCH AUTOSEL 6.15 06/34] arm64: Handle KCOV __init vs inline mismatches Sasha Levin
2025-08-03 21:18 ` [PATCH AUTOSEL 6.15 07/34] tpm: Check for completion after timeout Sasha Levin
2025-08-03 21:18 ` Sasha Levin [this message]
2025-08-03 21:18 ` [PATCH AUTOSEL 6.15 09/34] firmware: arm_ffa: Change initcall level of ffa_init() to rootfs_initcall Sasha Levin
2025-08-03 21:18 ` [PATCH AUTOSEL 6.15 10/34] smb/server: avoid deadlock when linking with ReplaceIfExists Sasha Levin
2025-08-03 21:18 ` [PATCH AUTOSEL 6.15 11/34] nvme-pci: try function level reset on init failure Sasha Levin
2025-08-03 21:18 ` [PATCH AUTOSEL 6.15 12/34] dm-stripe: limit chunk_sectors to the stripe size Sasha Levin
2025-08-03 21:18 ` [PATCH AUTOSEL 6.15 13/34] md/raid10: set chunk_sectors limit Sasha Levin
2025-08-03 21:18 ` [PATCH AUTOSEL 6.15 14/34] nvme-tcp: log TLS handshake failures at error level Sasha Levin
2025-08-03 21:18 ` [PATCH AUTOSEL 6.15 15/34] gfs2: Validate i_depth for exhash directories Sasha Levin
2025-08-03 21:18 ` [PATCH AUTOSEL 6.15 16/34] gfs2: Set .migrate_folio in gfs2_{rgrp,meta}_aops Sasha Levin
2025-08-03 21:18 ` [PATCH AUTOSEL 6.15 17/34] md: call del_gendisk in control path Sasha Levin
2025-08-03 21:18 ` [PATCH AUTOSEL 6.15 18/34] loop: Avoid updating block size under exclusive owner Sasha Levin
2025-08-03 21:18 ` [PATCH AUTOSEL 6.15 19/34] udf: Verify partition map count Sasha Levin
2025-08-03 21:18 ` [PATCH AUTOSEL 6.15 20/34] drbd: add missing kref_get in handle_write_conflicts Sasha Levin
2025-08-03 21:18 ` [PATCH AUTOSEL 6.15 21/34] hfs: fix not erasing deleted b-tree node issue Sasha Levin
2025-08-03 21:18 ` [PATCH AUTOSEL 6.15 22/34] better lockdep annotations for simple_recursive_removal() Sasha Levin
2025-08-03 21:18 ` [PATCH AUTOSEL 6.15 23/34] ata: ahci: Disallow LPM policy control if not supported Sasha Levin

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=20250803211836.3546094-8-sashal@kernel.org \
    --to=sashal@kernel.org \
    --cc=jarkko@kernel.org \
    --cc=linux-integrity@vger.kernel.org \
    --cc=patches@lists.linux.dev \
    --cc=peterhuewe@gmx.de \
    --cc=stable@vger.kernel.org \
    --cc=sudeep.holla@arm.com \
    --cc=yeoreum.yun@arm.com \
    --cc=zohar@linux.ibm.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