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 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. thanks, Mimi > --- > include/linux/lsm_hooks.h | 2 ++ > security/integrity/ima/ima_main.c | 2 +- > security/lsm_init.c | 13 +++++++++++-- > 3 files changed, 14 insertions(+), 3 deletions(-) > > diff --git a/include/linux/lsm_hooks.h b/include/linux/lsm_hooks.h > index d48bf0ad26f4..88fe105b7f00 100644 > --- a/include/linux/lsm_hooks.h > +++ b/include/linux/lsm_hooks.h > @@ -166,6 +166,7 @@ enum lsm_order { > * @initcall_fs: LSM callback for fs_initcall setup, optional > * @initcall_device: LSM callback for device_initcall() setup, optional > * @initcall_late: LSM callback for late_initcall() setup, optional > + * @initcall_late_sync: LSM callback for late_initcall_sync() setup, optional > */ > struct lsm_info { > const struct lsm_id *id; > @@ -181,6 +182,7 @@ struct lsm_info { > int (*initcall_fs)(void); > int (*initcall_device)(void); > int (*initcall_late)(void); > + int (*initcall_late_sync)(void); > }; > > #define DEFINE_LSM(lsm) \ > diff --git a/security/integrity/ima/ima_main.c b/security/integrity/ima/ima_main.c > index 1d6229b156fb..ace280fa3212 100644 > --- a/security/integrity/ima/ima_main.c > +++ b/security/integrity/ima/ima_main.c > @@ -1320,5 +1320,5 @@ DEFINE_LSM(ima) = { > .order = LSM_ORDER_LAST, > .blobs = &ima_blob_sizes, > /* Start IMA after the TPM is available */ > - .initcall_late = init_ima, > + .initcall_late_sync = init_ima, > }; > diff --git a/security/lsm_init.c b/security/lsm_init.c > index 573e2a7250c4..4e5c59beb82a 100644 > --- a/security/lsm_init.c > +++ b/security/lsm_init.c > @@ -547,13 +547,22 @@ device_initcall(security_initcall_device); > * security_initcall_late - Run the LSM late initcalls > */ > static int __init security_initcall_late(void) > +{ > + return lsm_initcall(late); > +} > +late_initcall(security_initcall_late); > + > +/** > + * security_initcall_late_sync - Run the LSM late initcalls sync > + */ > +static int __init security_initcall_late_sync(void) > { > int rc; > > - rc = lsm_initcall(late); > + rc = lsm_initcall(late_sync); > lsm_pr_dbg("all enabled LSMs fully activated\n"); > call_blocking_lsm_notifier(LSM_STARTED_ALL, NULL); > > return rc; > } > -late_initcall(security_initcall_late); > +late_initcall_sync(security_initcall_late_sync); > -- > LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7} >