[PATCH v5 3/4] security: ima: rename boot_aggregate when ima is initialised at late_sync
Yeoreum Yun
yeoreum.yun at arm.com
Mon Jun 1 14:27:48 UTC 2026
From: Jonathan McDowell <noodles at meta.com>
The Linux IMA (Integrity Measurement Architecture) subsystem used for
secure boot, file integrity, or remote attestation cannot be a loadable
module for few reasons listed below:
o Boot-Time Integrity: IMA’s main role is to measure and appraise files
before they are used. This includes measuring critical system files
during early boot (e.g., init, init scripts, login binaries). If IMA
were a module, it would be loaded too late to cover those.
o TPM Dependency: IMA integrates tightly with the TPM to record
measurements into PCRs. The TPM must be initialized early (ideally
before init_ima()), which aligns with IMA being built-in.
o Security Model: IMA is part of a Trusted Computing Base (TCB). Making
it a module would weaken the security model, as a potentially
compromised system could delay or tamper with its initialization.
IMA must be built-in to ensure it starts measuring from the earliest
possible point in boot which inturn implies TPM must be initialised and
ready to use before IMA.
Unfortunately some TPM drivers (such as Arm FF-A, or SPI attached TPM
devices) are not reliably available during the initcall_late stage,
resulting in a log error:
ima: No TPM chip found, activating TPM-bypass!
To address this issue, IMA_INIT_LATE_SYNC is introduced.
However, a remote attestation service cannot determine when IMA has been
initialized because the boot_aggregate measurement name remains unchanged,
even though IMA is initialized later at late_initcall_sync when
IMA_INIT_LATE_SYNC is enabled.
Therefore, use a distinct boot_aggregate name when IMA_INIT_LATE_SYNC
is enabled, allowing the remote attestation service to identify
when IMA has been initialized.
Signed-off-by: Jonathan McDowell <noodles at meta.com>
[yeoreum.yun at arm.com: modified to align with the IMA_INIT_LATE_SYNC change]
---
security/integrity/ima/ima.h | 1 +
security/integrity/ima/ima_init.c | 15 +++++++++++----
security/integrity/ima/ima_template_lib.c | 3 ++-
3 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 69e9bf0b82c6..194b195cec1e 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -66,6 +66,7 @@ extern struct ima_algo_desc *ima_algo_array __ro_after_init;
extern int ima_appraise;
extern struct tpm_chip *ima_tpm_chip;
extern const char boot_aggregate_name[];
+extern const char boot_aggregate_late_name[];
/* IMA event related data */
struct ima_event_data {
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
index a2f34f2d8ad7..4c24bd535466 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -22,6 +22,7 @@
/* name for boot aggregate entry */
const char boot_aggregate_name[] = "boot_aggregate";
+const char boot_aggregate_late_name[] = "boot_aggregate_late";
struct tpm_chip *ima_tpm_chip;
/* Add the boot aggregate to the IMA measurement list and extend
@@ -45,11 +46,11 @@ static int __init ima_add_boot_aggregate(void)
const char *audit_cause = "ENOMEM";
struct ima_template_entry *entry;
struct ima_iint_cache tmp_iint, *iint = &tmp_iint;
- struct ima_event_data event_data = { .iint = iint,
- .filename = boot_aggregate_name };
+ struct ima_event_data event_data = { .iint = iint };
struct ima_max_digest_data hash;
struct ima_digest_data *hash_hdr = container_of(&hash.hdr,
struct ima_digest_data, hdr);
+ const char *filename;
int result = -ENOMEM;
int violation = 0;
@@ -59,6 +60,12 @@ static int __init ima_add_boot_aggregate(void)
iint->ima_hash->algo = ima_hash_algo;
iint->ima_hash->length = hash_digest_size[ima_hash_algo];
+ if (IS_ENABLED(CONFIG_IMA_INIT_LATE_SYNC))
+ filename = boot_aggregate_late_name;
+ else
+ filename = boot_aggregate_name;
+ event_data.filename = filename;
+
/*
* With TPM 2.0 hash agility, TPM chips could support multiple TPM
* PCR banks, allowing firmware to configure and enable different
@@ -86,7 +93,7 @@ static int __init ima_add_boot_aggregate(void)
}
result = ima_store_template(entry, violation, NULL,
- boot_aggregate_name,
+ filename,
CONFIG_IMA_MEASURE_PCR_IDX);
if (result < 0) {
ima_free_template_entry(entry);
@@ -95,7 +102,7 @@ static int __init ima_add_boot_aggregate(void)
}
return 0;
err_out:
- integrity_audit_msg(AUDIT_INTEGRITY_PCR, NULL, boot_aggregate_name, op,
+ integrity_audit_msg(AUDIT_INTEGRITY_PCR, NULL, filename, op,
audit_cause, result, 0);
return result;
}
diff --git a/security/integrity/ima/ima_template_lib.c b/security/integrity/ima/ima_template_lib.c
index 0e627eac9c33..8a89236f926c 100644
--- a/security/integrity/ima/ima_template_lib.c
+++ b/security/integrity/ima/ima_template_lib.c
@@ -363,7 +363,8 @@ int ima_eventdigest_init(struct ima_event_data *event_data,
goto out;
}
- if ((const char *)event_data->filename == boot_aggregate_name) {
+ if ((const char *)event_data->filename == boot_aggregate_name ||
+ (const char *)event_data->filename == boot_aggregate_late_name) {
if (ima_tpm_chip) {
hash.hdr.algo = HASH_ALGO_SHA1;
result = ima_calc_boot_aggregate(hash_hdr);
--
LEVI:{C3F47F37-75D8-414A-A8BA-3980EC8A46D7}
More information about the Linux-security-module-archive
mailing list