public inbox for linux-security-module@vger.kernel.org
 help / color / mirror / Atom feed
From: Yeoreum Yun <yeoreum.yun@arm.com>
To: Mimi Zohar <zohar@linux.ibm.com>
Cc: David Safford <david.safford@gmail.com>,
	Jonathan McDowell <noodles@earth.li>,
	linux-security-module@vger.kernel.org,
	linux-kernel@vger.kernel.org, linux-integrity@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org, kvmarm@lists.linux.dev,
	paul@paul-moore.com, jmorris@namei.org, serge@hallyn.com,
	roberto.sassu@huawei.com, dmitry.kasatkin@gmail.com,
	eric.snowberg@oracle.com, jarkko@kernel.org, jgg@ziepe.ca,
	sudeep.holla@kernel.org, maz@kernel.org, oupton@kernel.org,
	joey.gouly@arm.com, suzuki.poulose@arm.com, yuzenghui@huawei.com,
	catalin.marinas@arm.com, will@kernel.org, noodles@meta.com,
	sebastianene@google.com
Subject: Re: [PATCH] ima: debugging late_initcall_sync measurements
Date: Wed, 6 May 2026 14:57:12 +0100	[thread overview]
Message-ID: <aftIuPwNeuzc9nY1@e129823.arm.com> (raw)
In-Reply-To: <9ff4853a8e9932b3a1424f2a6c3347f1723fb5f4.camel@linux.ibm.com>

Hi Mimi,

> On Wed, 2026-05-06 at 06:54 +0100, Yeoreum Yun wrote:
> > Hi Mimi,
> > 
> > > On Sun, 2026-05-03 at 07:36 -0400, Mimi Zohar wrote:
> > > > On Fri, 2026-05-01 at 12:52 -0400, David Safford wrote:
> > > > > On Thu, Apr 30, 2026 at 5:43 PM Mimi Zohar <zohar@linux.ibm.com> wrote:
> > > > > > 
> > > > > > On Thu, 2026-04-30 at 10:48 +0100, Yeoreum Yun wrote:
> > > > > > > With above change I confirmed there is no meaurement log
> > > > > > > between boot_aggregate and boot_aggregate_late except "kernel_version"
> > > > > > > But this is ignorable since this UTS measurement is done in
> > > > > > > "ima_init_core() (old: ima_init())" and it is part of ima initialisation.
> > > > > > > 
> > > > > > > 1. ima_policy=tcb
> > > > > > > 
> > > > > > >   # cat /sys/kernel/security/ima/ascii_runtime_measurements
> > > > > > >   10 0adefe762c149c7cec19da62f0da1297fcfbffff ima-ng sha256:0000000000000000000000000000000000000000000000000000000000000000 boot_aggregate
> > > > > > >   10 4e5d73ebadfd8f850cb93ce4de755ba148a9a7d5 ima-ng sha256:0000000000000000000000000000000000000000000000000000000000000000 boot_aggregate_late
> > > > > > >   10 7c23cc970eceec906f7a41bc2fbde770d7092209 ima-ng sha256:72ade6ae3d35cfe5ede7a77b1c0ed1d1782a899445fdcb219c0e994a084a70d5 /bin/busybox
> > > > > snip
> > > > > > > 
> > > > > > > 2. ima_policy=critical_data
> > > > > > > 
> > > > > > >   # cat /sys/kernel/security/ima/ascii_runtime_measurements
> > > > > > >   10 0adefe762c149c7cec19da62f0da1297fcfbffff ima-ng sha256:0000000000000000000000000000000000000000000000000000000000000000 boot_aggregate
> > > > > > >   10 49ab61dd97ea2f759edcb6c6a3387ac67f0aa576 ima-buf sha256:0c907aab3261194f16b0c2a422a82f145bc9b9ecb8fdb633fa43e3e5379f0af2 kernel_version 372e312e302d7263312b // Ignorable since it's generated by ima_init(_core)().
> > > > > > >   10 4e5d73ebadfd8f850cb93ce4de755ba148a9a7d5 ima-ng sha256:0000000000000000000000000000000000000000000000000000000000000000 boot_aggregate_late
> > > > > > > 
> > > > > > > Therefore, init_ima() could move into late_initcall_sync like v1 did:
> > > > > > >   - https://lore.kernel.org/all/20260417175759.3191279-2-yeoreum.yun@arm.com/
> > > > > > 
> > > > > > Thanks, Yeoreum.  It's a bit premature to claim it's "safe" to move the
> > > > > > initcall.  Hopefully others will respond.
> > > > > > 
> > > > > > Mimi
> > > > > 
> > > > > I have also run with this patch on a number of bare metal and virtual machines,
> > > > > running everything from default Fedora 44 to a version with everything turned on
> > > > > (uefi secure boot, UKI with sdboot stub measurements, IMA measurement
> > > > > and appraisal enabled,
> > > > > all systemd measurements on, and systemd using the TPM for root
> > > > > partition decryption.)
> > > > > I too see only the kernel_version event between the normal and late
> > > > > calls, if ima_policy=critical_data.
> > > > 
> > > > Thanks, Dave!  Were all the systems you tested x86_64?  The next step would be
> > > > to test on different arch's (e.g. Z, Power).
> > > 
> > > On both Z and PowerVM, there are ~30 measurements between boot_aggregate and
> > > boot_aggregate_late.  For example, on PowerVM:
> > > 
> > > # grep -n boot_aggregate
> > > /sys/kernel/security/integrity/ima/ascii_runtime_measurements
> > > 
> > > 1:10 f60a05d7354fb34aabc02965216abd3428ea52bb ima-sig
> > > sha256:9887dd089ee19a6517bca10580b02c1bb9aa6cd86c157b6ead8a1c0403f348d5
> > > boot_aggregate 
> > > 31:10 e2592b0d61da6300d3db447b143897a9792231ea ima-sig
> > > sha256:9887dd089ee19a6517bca10580b02c1bb9aa6cd86c157b6ead8a1c0403f348d5
> > > boot_aggregate_late
> > > 
> > > It would be interesting to the results from a Raspberry Pi 5 as well,
> > > with/without a TPM.
> > 
> > Honestly, I find this result hard to accept.
> > 
> > This effectively means that there is code invoking IMA measurement during late_initcall().
> > It also implies that if, in the future, a late_initcall is added that performs
> > an IMA measurement before IMA initialization has occurred accoding to order by linker,
> > that measurement could be missed.
> 
> Exactly.  The results are simply from booting with the builtin "tcb" and
> "critical_data" policies.
> 
> $ sudo grubby --args="ima_policy=\"tcb|critical_data\"" --update-kernel
> /boot/vmlinuz-${SUFFIX}

Thanks. but I still wonder what meaasurements there are between
boot_aggregate and boot_aggregate_late.
Might be there would be key measurements if it takes more than
5 mins before generating boot_aggregate_late but this seems rare.

If you don't mind, would you share the contents of the log between
boot_aggregate and boot_aggregate_late?
since I only get a kernel_version in my environment.

And I think we can collect missing measurements before ima_init_core()
into another separate list than ima_measurements in ima_add_template_entry() and
we can extend them after boot_aggreagate log generation at ima_init_core()
then ima initialisation could be moved to late_initcall_sync like
(just for a test and share concept):

-------&<-------
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 9a1117112fb2..737c1ac8ad77 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -67,6 +67,7 @@ extern int ima_appraise;
 extern struct tpm_chip *ima_tpm_chip;
 extern const char boot_aggregate_name[];
 extern const char boot_aggregate_late_name[];
+extern bool ima_extend_on;

 /* IMA event related data */
 struct ima_event_data {
@@ -107,6 +108,7 @@ struct ima_template_desc {

:...skipping...
diff --git a/security/integrity/ima/ima.h b/security/integrity/ima/ima.h
index 9a1117112fb2..737c1ac8ad77 100644
--- a/security/integrity/ima/ima.h
+++ b/security/integrity/ima/ima.h
@@ -67,6 +67,7 @@ extern int ima_appraise;
 extern struct tpm_chip *ima_tpm_chip;
 extern const char boot_aggregate_name[];
 extern const char boot_aggregate_late_name[];
+extern bool ima_extend_on;

 /* IMA event related data */
 struct ima_event_data {
@@ -107,6 +108,7 @@ struct ima_template_desc {

 struct ima_template_entry {
        int pcr;
+       int violation;
        struct tpm_digest *digests;
        struct ima_template_desc *template_desc; /* template descriptor */
        u32 template_data_len;
@@ -317,6 +319,7 @@ unsigned long ima_get_binary_runtime_size(void);
 int ima_init_template(void);
 void ima_init_template_list(void);
 int __init ima_init_digests(void);
+int __init ima_extend_deferred(void);
 void __init ima_init_reboot_notifier(void);
 int ima_lsm_policy_change(struct notifier_block *nb, unsigned long event,
                          void *lsm_data);
diff --git a/security/integrity/ima/ima_init.c b/security/integrity/ima/ima_init.c
index edd063b99685..f6a2b53c1dcb 100644
--- a/security/integrity/ima/ima_init.c
+++ b/security/integrity/ima/ima_init.c
@@ -149,10 +149,22 @@ int __init ima_init_core(bool late)
        rc = ima_init_digests();
        if (rc != 0)
                return rc;
+
+       ima_extend_on = true;
+
        rc = ima_add_boot_aggregate(late);      /* boot aggregate must be first entry */
        if (rc != 0)
                return rc;

+       /* This is just for a test. */
+       if (!late)
+               ima_extend_on = false;
+       else  {
+               rc = ima_extend_deferred();
+               if (rc != 0)
+                       return rc;
+       }
+
        ima_init_policy();

        rc = ima_fs_init();
diff --git a/security/integrity/ima/ima_queue.c b/security/integrity/ima/ima_queue.c
index 319522450854..81f2ee070fee 100644
--- a/security/integrity/ima/ima_queue.c
+++ b/security/integrity/ima/ima_queue.c
@@ -22,10 +22,13 @@

 #define AUDIT_CAUSE_LEN_MAX 32

+bool ima_extend_on;
+
 /* pre-allocated array of tpm_digest structures to extend a PCR */
 static struct tpm_digest *digests;

 LIST_HEAD(ima_measurements);   /* list of all measurements */
+static LIST_HEAD(ima_extend_deferred_head);
 #ifdef CONFIG_IMA_KEXEC
 static unsigned long binary_runtime_size;
 #else
@@ -91,6 +94,7 @@ static int get_binary_runtime_size(struct ima_template_entry *entry)
        return size;
 }

+
 /* ima_add_template_entry helper function:
  * - Add template entry to the measurement list and hash table, for
  *   all entries except those carried across kexec.
@@ -98,7 +102,8 @@ static int get_binary_runtime_size(struct ima_template_entry *entry)
  * (Called with ima_extend_list_mutex held.)
  */
 static int ima_add_digest_entry(struct ima_template_entry *entry,
-                               bool update_htable)
+                               bool update_htable,
+                               struct list_head *measurements_list)
 {
        struct ima_queue_entry *qe;
        unsigned int key;
@@ -111,7 +116,7 @@ static int ima_add_digest_entry(struct ima_template_entry *entry,
        qe->entry = entry;

        INIT_LIST_HEAD(&qe->later);
-       list_add_tail_rcu(&qe->later, &ima_measurements);
+       list_add_tail_rcu(&qe->later, measurements_list);

        atomic_long_inc(&ima_htable.len);
        if (update_htable) {
@@ -173,6 +178,7 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation,
        char tpm_audit_cause[AUDIT_CAUSE_LEN_MAX];
        int audit_info = 1;
        int result = 0, tpmresult = 0;
+       struct list_head *measurements_list;

        mutex_lock(&ima_extend_list_mutex);

@@ -195,15 +201,21 @@ int ima_add_template_entry(struct ima_template_entry *entry, int violation,
                }
        }

+
+       entry->violation = violation;
+       measurements_list = (ima_extend_on) ? &ima_measurements :
+                                             &ima_extend_deferred_head;
+
        result = ima_add_digest_entry(entry,
-                                     !IS_ENABLED(CONFIG_IMA_DISABLE_HTABLE));
+                                     !IS_ENABLED(CONFIG_IMA_DISABLE_HTABLE),
+                                     measurements_list);
        if (result < 0) {
                audit_cause = "ENOMEM";
                audit_info = 0;
                goto out;
        }

-       if (violation)          /* invalidate pcr */
+       if (violation)                  /* invalidate pcr */
                digests_arg = digests;

        tpmresult = ima_pcr_extend(digests_arg, entry->pcr);
@@ -225,7 +237,7 @@ int ima_restore_measurement_entry(struct ima_template_entry *entry)
        int result = 0;

        mutex_lock(&ima_extend_list_mutex);
-       result = ima_add_digest_entry(entry, 0);
+       result = ima_add_digest_entry(entry, 0, &ima_measurements);
        mutex_unlock(&ima_extend_list_mutex);
        return result;
 }
@@ -288,3 +300,23 @@ int __init ima_init_digests(void)

        return 0;
 }
+
+int __init ima_extend_deferred(void)
+{
+       guard(mutex)(&ima_extend_list_mutex);
+       struct ima_queue_entry *qe;
+       struct tpm_digest *digests_arg;
+       int ret = 0;
+
+       list_for_each_entry(qe, &ima_extend_deferred_head, later) {
+               digests_arg = (qe->entry->violation) ? digests : qe->entry->digests;
+               ret = ima_pcr_extend(digests_arg, qe->entry->pcr);
+               if (ret)
+                       /* TODO: audit? */
+                       break;
+       }
+
+       list_splice_tail_init(&ima_extend_deferred_head, &ima_measurements);
+
+       return ret;
+}

-- 
Sincerely,
Yeoreum Yun

      reply	other threads:[~2026-05-06 13:57 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-24 13:23 [RFC PATCH v3 0/4] Fix IMA + TPM initialisation ordering issue Jonathan McDowell
2026-04-24 13:24 ` [RFC PATCH v3 1/4] lsm: Allow LSMs to register for late_initcall_sync init Jonathan McDowell
2026-04-24 13:24 ` [RFC PATCH v3 2/4] security: ima: call ima_init() again at late_initcall_sync for defered TPM Jonathan McDowell
2026-04-24 16:55   ` Yeoreum Yun
2026-04-24 20:25   ` Mimi Zohar
2026-04-25  9:10     ` Jonathan McDowell
2026-04-24 13:24 ` [RFC PATCH v3 3/4] Revert "tpm: tpm_crb_ffa: try to probe tpm_crb_ffa when it's built-in" Jonathan McDowell
2026-04-24 16:10   ` Sudeep Holla
2026-04-24 13:24 ` [RFC PATCH v3 4/4] Revert "firmware: arm_ffa: Change initcall level of ffa_init() to rootfs_initcall" Jonathan McDowell
2026-04-24 16:09   ` Sudeep Holla
2026-04-25 14:19   ` Jarkko Sakkinen
2026-04-29 20:01 ` [PATCH] ima: debugging late_initcall_sync measurements Mimi Zohar
2026-04-30  9:48   ` Yeoreum Yun
2026-04-30 21:39     ` Mimi Zohar
2026-04-30 22:35       ` Paul Moore
2026-05-01  1:51         ` Mimi Zohar
2026-05-03 16:46           ` Paul Moore
2026-05-04 12:02             ` Mimi Zohar
2026-05-04 20:51               ` Paul Moore
2026-05-05 21:02                 ` Mimi Zohar
2026-05-05 22:55                   ` Paul Moore
2026-05-06  1:51                     ` Mimi Zohar
2026-05-06  2:11                       ` Paul Moore
2026-05-01 16:52       ` David Safford
2026-05-03 11:36         ` Mimi Zohar
2026-05-03 12:42           ` Mimi Zohar
2026-05-06  5:54             ` Yeoreum Yun
2026-05-06  7:23               ` Yeoreum Yun
2026-05-06 11:47               ` Mimi Zohar
2026-05-06 13:57                 ` Yeoreum Yun [this message]

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=aftIuPwNeuzc9nY1@e129823.arm.com \
    --to=yeoreum.yun@arm.com \
    --cc=catalin.marinas@arm.com \
    --cc=david.safford@gmail.com \
    --cc=dmitry.kasatkin@gmail.com \
    --cc=eric.snowberg@oracle.com \
    --cc=jarkko@kernel.org \
    --cc=jgg@ziepe.ca \
    --cc=jmorris@namei.org \
    --cc=joey.gouly@arm.com \
    --cc=kvmarm@lists.linux.dev \
    --cc=linux-arm-kernel@lists.infradead.org \
    --cc=linux-integrity@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-security-module@vger.kernel.org \
    --cc=maz@kernel.org \
    --cc=noodles@earth.li \
    --cc=noodles@meta.com \
    --cc=oupton@kernel.org \
    --cc=paul@paul-moore.com \
    --cc=roberto.sassu@huawei.com \
    --cc=sebastianene@google.com \
    --cc=serge@hallyn.com \
    --cc=sudeep.holla@kernel.org \
    --cc=suzuki.poulose@arm.com \
    --cc=will@kernel.org \
    --cc=yuzenghui@huawei.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