[PATCH v3 31/34] ima,evm: move initcalls to the LSM framework

Paul Moore paul at paul-moore.com
Fri Aug 22 20:45:01 UTC 2025


On Thu, Aug 14, 2025 at 6:55 PM Paul Moore <paul at 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 <paul at 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?

> 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

-- 
paul-moore.com



More information about the Linux-security-module-archive mailing list