Re: [RFC PATCH 1/4] security: ima: move ima_init into late_initcall_sync

Mimi Zohar <[email protected]>
Newsgroups org.kernel.vger.linux-integrity,dev.linux.lists.kvmarm,org.infradead.lists.linux-arm-kernel,org.kernel.vger.linux-kernel,org.kernel.vger.linux-security-module
Message-ID <[email protected]>
On Tue, 2026-04-21 at 13:50 +0100, Yeoreum Yun wrote:
> Hi Mimi,
> 
> > On Fri, 2026-04-17 at 18:57 +0100, Yeoreum Yun wrote:
> > > To generate the boot_aggregate log in the IMA subsystem with 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.
> > > 
> > > To ensure the TPM device operating over the FF-A protocol with
> > > the CRB interface is probed before IMA initialization,
> > > the following conditions must be met:
> > > 
> > >    1. The corresponding ffa_device must be registered,
> > >       which is done via ffa_init().
> > > 
> > >    2. The tpm_crb_driver must successfully probe this device via
> > >       tpm_crb_ffa_init().
> > > 
> > >    3. The tpm_crb driver using CRB over FF-A can then
> > >       be probed successfully. (See crb_acpi_add() and
> > >       tpm_crb_ffa_init() for reference.)
> > > 
> > > Unfortunately, ffa_init(), tpm_crb_ffa_init(), and crb_acpi_driver_init() are
> > > all registered with device_initcall, which means crb_acpi_driver_init() may
> > > be invoked before ffa_init() and tpm_crb_ffa_init() are completed.
> > > 
> > > When this occurs, probing the TPM device is deferred.
> > > However, the deferred probe can happen after the IMA subsystem
> > > has already been initialized, since IMA initialization is performed
> > > during late_initcall, and deferred_probe_initcall() is performed
> > > at the same level.
> > > 
> > > To resolve this, move ima_init() into late_inicall_sync level
> > > so that let IMA not miss TPM PCR value when generating boot_aggregate
> > > log though TPM device presents in the system.
> > > 
> > > Signed-off-by: Yeoreum Yun <[email protected]>
> > 
> > IMA should be initialized as early as possible. I'm really hesitant to defer
> > ima_init() to late_initcall_sync() for systems that the TPM is currently
> > initialized in time. For these systems, continue initializing IMA at
> > late_initcall(). As a compromise for those systems that the TPM isn't properly
> > initialized in time, define and instantiate the late_initcall_sync().
> > 
> > ima_init() would need to differentiate between the late_initcall and
> > late_initcall_sync.  On late_initcall(), instead of saying "No TPM chip found,
> > activating TPM-bypass!",  it should say "No TPM chip found, deferring to
> > late_initcall_sync" or something similar.
> 
> But can we really move those initialisations to be called again?
> 
> I am referring to functions such as ima_init_crypto(),
> ima_add_boot_aggregate(), and ima_measure_critical_data() in ima_init()—
> first without TPM, and then a second time once TPM becomes available.
> I don’t think that approach would work.
> 
> In other words, unless tpm_default_chip() can differentiate between a TPM
> device that is deferred and one that does not exist, we cannot distinguish
> between the “defer” case and “-EEXIST”.
> 
> It might be possible if the TPM core tracked the state when a driver returns
> -EPROBE_DEFER, but I am not sure that is the right approach.
> For deferred probe cases, the “device initialised in time” check should
> likely be done at late_initcall_sync, rather than late_initcall.
> 
> This implies that any such check performed before late_initcall_sync
> does not reflect a valid state, as it cannot distinguish between “not
> present” and “deferred”.
> 
> Therefore, I think the TPM check in IMA should be performed at
> late_initcall_sync.
> 
> 
> Am I missing something?

In ima_init() you short circuit out, when called by late_initcall(), if the TPM
hasn't been initialized.  So the rest of the ima_init() isn't called.  Roughly
something like this (needs some cleanup):

int __init ima_init(void)
{
        static int first = 1;
        int rc;

        if (ima_tpm_chip)
                return 0;

        ima_tpm_chip = tpm_default_chip();
        if (!ima_tpm_chip && first) {
                pr_info("No TPM chip found, deferring te late_initcall_sync()\n");
                first = 0;
                return 0;
        }

The rest of the code remains the same.

Mimi
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.