On Fri, 2025-08-22 at 16:45 -0400, Paul Moore wrote:
> On Thu, Aug 14, 2025 at 6:55 PM Paul Moore <p...@paul-moore.com> wrote:
> > 
> > This patch converts IMA and EVM to use the LSM frameworks's initcall
> > mechanism.  There was a minor challenge in this conversion that wasn't
> > seen when converting the other LSMs brought about by the resource
> > sharing between the two related, yes independent IMA and EVM LSMs.
> > This was resolved by registering the same initcalls for each LSM and
> > including code in each registered initcall to ensure it only executes
> > once during each boot.
> > 
> > It is worth mentioning that this patch does not touch any of the
> > "platform certs" code that lives in the security/integrity/platform_certs
> > directory as the IMA/EVM maintainers have assured me that this code is
> > unrelated to IMA/EVM, despite the location, and will be moved to a more
> > relevant subsystem in the future.
> > 
> > Signed-off-by: Paul Moore <p...@paul-moore.com>
> > ---
> >  security/integrity/Makefile       |  2 +-
> >  security/integrity/evm/evm_main.c |  6 ++---
> >  security/integrity/iint.c         |  4 +--
> >  security/integrity/ima/ima_main.c |  6 ++---
> >  security/integrity/initcalls.c    | 41 +++++++++++++++++++++++++++++++
> >  security/integrity/initcalls.h    | 28 +++++++++++++++++++++
> >  6 files changed, 78 insertions(+), 9 deletions(-)
> >  create mode 100644 security/integrity/initcalls.c
> >  create mode 100644 security/integrity/initcalls.h
> 
> Mimi, Roberto, I believe I've incorporated all of your feedback thus
> far, does this patch look okay to you?  If so, can I get an ACK from
> one or both of you?

I just realized that it could be rewritten without exposing the IMA and
EVM init functions. I also added the logic to cleanup the integrity
directory itself.

Sending soon...

Roberto

> > diff --git a/security/integrity/Makefile b/security/integrity/Makefile
> > index 92b63039c654..6ea330ea88b1 100644
> > --- a/security/integrity/Makefile
> > +++ b/security/integrity/Makefile
> > @@ -5,7 +5,7 @@
> > 
> >  obj-$(CONFIG_INTEGRITY) += integrity.o
> > 
> > -integrity-y := iint.o
> > +integrity-y := iint.o initcalls.o
> >  integrity-$(CONFIG_INTEGRITY_AUDIT) += integrity_audit.o
> >  integrity-$(CONFIG_INTEGRITY_SIGNATURE) += digsig.o
> >  integrity-$(CONFIG_INTEGRITY_ASYMMETRIC_KEYS) += digsig_asymmetric.o
> > diff --git a/security/integrity/evm/evm_main.c 
> > b/security/integrity/evm/evm_main.c
> > index db8e324ed4e6..823573bcaa27 100644
> > --- a/security/integrity/evm/evm_main.c
> > +++ b/security/integrity/evm/evm_main.c
> > @@ -25,6 +25,7 @@
> >  #include <crypto/hash.h>
> >  #include <crypto/hash_info.h>
> >  #include <crypto/utils.h>
> > +#include "../initcalls.h"
> >  #include "evm.h"
> > 
> >  int evm_initialized;
> > @@ -1112,7 +1113,7 @@ void __init evm_load_x509(void)
> >  }
> >  #endif
> > 
> > -static int __init init_evm(void)
> > +int __init init_evm(void)
> >  {
> >         int error;
> >         struct list_head *pos, *q;
> > @@ -1179,6 +1180,5 @@ DEFINE_LSM(evm) = {
> >         .init = init_evm_lsm,
> >         .order = LSM_ORDER_LAST,
> >         .blobs = &evm_blob_sizes,
> > +       .initcall_late = integrity_late_init,
> >  };
> > -
> > -late_initcall(init_evm);
> > diff --git a/security/integrity/iint.c b/security/integrity/iint.c
> > index 068ac6c2ae1e..a4b88d67ff43 100644
> > --- a/security/integrity/iint.c
> > +++ b/security/integrity/iint.c
> > @@ -11,6 +11,7 @@
> >   */
> >  #include <linux/security.h>
> >  #include "integrity.h"
> > +#include "initcalls.h"
> > 
> >  struct dentry *integrity_dir;
> > 
> > @@ -42,7 +43,7 @@ void __init integrity_load_keys(void)
> >                 evm_load_x509();
> >  }
> > 
> > -static int __init integrity_fs_init(void)
> > +int __init integrity_fs_init(void)
> >  {
> >         integrity_dir = securityfs_create_dir("integrity", NULL);
> >         if (IS_ERR(integrity_dir)) {
> > @@ -58,4 +59,3 @@ static int __init integrity_fs_init(void)
> >         return 0;
> >  }
> > 
> > -late_initcall(integrity_fs_init)
> > diff --git a/security/integrity/ima/ima_main.c 
> > b/security/integrity/ima/ima_main.c
> > index eade8e1e3cb1..06ae59cd77f4 100644
> > --- a/security/integrity/ima/ima_main.c
> > +++ b/security/integrity/ima/ima_main.c
> > @@ -28,6 +28,7 @@
> >  #include <linux/iversion.h>
> >  #include <linux/evm.h>
> >  #include <linux/crash_dump.h>
> > +#include "../initcalls.h"
> > 
> >  #include "ima.h"
> > 
> > @@ -1202,7 +1203,7 @@ static int ima_kernel_module_request(char *kmod_name)
> > 
> >  #endif /* CONFIG_INTEGRITY_ASYMMETRIC_KEYS */
> > 
> > -static int __init init_ima(void)
> > +int __init init_ima(void)
> >  {
> >         int error;
> > 
> > @@ -1283,6 +1284,5 @@ DEFINE_LSM(ima) = {
> >         .init = init_ima_lsm,
> >         .order = LSM_ORDER_LAST,
> >         .blobs = &ima_blob_sizes,
> > +       .initcall_late = integrity_late_init,
> >  };
> > -
> > -late_initcall(init_ima);       /* Start IMA after the TPM is available */
> > diff --git a/security/integrity/initcalls.c b/security/integrity/initcalls.c
> > new file mode 100644
> > index 000000000000..6afa411068f2
> > --- /dev/null
> > +++ b/security/integrity/initcalls.c
> > @@ -0,0 +1,41 @@
> > +// SPDX-License-Identifier: GPL-2.0+
> > +/*
> > + * IMA/EVM initcalls
> > + *
> > + */
> > +
> > +#include <linux/init.h>
> > +
> > +#include "initcalls.h"
> > +
> > +/**
> > + * integrity_late_init - late_initcalls for IMA/EVM
> > + *
> > + * This helper function wraps all of the late_initcalls for both IMA and 
> > EVM.
> > + * It can be called multiple times, e.g. once from IMA and once from EVM,
> > + * without problem as it maintains an internal static state variable which
> > + * ensures that any setup/initialization is only done once.
> > + */
> > +int __init integrity_late_init(void)
> > +{
> > +       int rc = 0, rc_tmp;
> > +       static bool setup = false;
> > +
> > +       if (setup)
> > +               return 0;
> > +       setup = true;
> > +
> > +       rc_tmp = integrity_fs_init();
> > +       if (!rc && rc_tmp)
> > +               rc = rc_tmp;
> > +
> > +       rc_tmp = init_ima();
> > +       if (!rc && rc_tmp)
> > +               rc = rc_tmp;
> > +
> > +       rc_tmp = init_evm();
> > +       if (!rc && rc_tmp)
> > +               rc = rc_tmp;
> > +
> > +       return rc;
> > +}
> > diff --git a/security/integrity/initcalls.h b/security/integrity/initcalls.h
> > new file mode 100644
> > index 000000000000..b56e9c576505
> > --- /dev/null
> > +++ b/security/integrity/initcalls.h
> > @@ -0,0 +1,28 @@
> > +/* SPDX-License-Identifier: GPL-2.0 */
> > +
> > +#ifndef _INTEGRITY_INITCALLS_H
> > +#define _INTEGRITY_INITCALLS_H
> > +
> > +int integrity_fs_init(void);
> > +
> > +#ifdef CONFIG_IMA
> > +int init_ima(void);
> > +#else
> > +static inline int init_ima(void)
> > +{
> > +       return 0;
> > +}
> > +#endif
> > +
> > +#ifdef CONFIG_EVM
> > +int init_evm(void);
> > +#else
> > +static inline int init_evm(void)
> > +{
> > +       return 0;
> > +}
> > +#endif
> > +
> > +int integrity_late_init(void);
> > +
> > +#endif
> > --
> > 2.50.1
> 


Reply via email to