summaryrefslogtreecommitdiff
path: root/security/lsm_init.c
diff options
context:
space:
mode:
authorPaul Moore <paul@paul-moore.com>2025-02-11 12:18:35 -0500
committerPaul Moore <paul@paul-moore.com>2025-10-22 19:24:24 -0400
commitcdc028812f727907d1575cf454a5f01ddffa7750 (patch)
treee7f1fbfa4d1916f6ac899123c1d25046cb59d7a3 /security/lsm_init.c
parent3423c6397ce21356c3c2fac0b2727d428d96cfa4 (diff)
lsm: introduce an initcall mechanism into the LSM framework
Currently the individual LSMs register their own initcalls, and while this should be harmless, it can be wasteful in the case where a LSM is disabled at boot as the initcall will still be executed. This patch introduces support for managing the initcalls in the LSM framework, and future patches will convert the existing LSMs over to this new mechanism. Only initcall types which are used by the current in-tree LSMs are supported, additional initcall types can easily be added in the future if needed. Reviewed-by: Kees Cook <kees@kernel.org> Reviewed-by: Casey Schaufler <casey@schaufler-ca.com> Reviewed-by: John Johansen <john.johhansen@canonical.com> Reviewed-by: Mimi Zohar <zohar@linux.ibm.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
Diffstat (limited to 'security/lsm_init.c')
-rw-r--r--security/lsm_init.c89
1 files changed, 89 insertions, 0 deletions
diff --git a/security/lsm_init.c b/security/lsm_init.c
index fd69bde9112e..aacdac406ba5 100644
--- a/security/lsm_init.c
+++ b/security/lsm_init.c
@@ -39,6 +39,27 @@ static __initdata struct lsm_info *lsm_exclusive;
for ((iter) = __start_early_lsm_info; \
(iter) < __end_early_lsm_info; (iter)++)
+#define lsm_initcall(level) \
+ ({ \
+ int _r, _rc = 0; \
+ struct lsm_info **_lp, *_l; \
+ lsm_order_for_each(_lp) { \
+ _l = *_lp; \
+ if (!_l->initcall_##level) \
+ continue; \
+ lsm_pr_dbg("running %s %s initcall", \
+ _l->id->name, #level); \
+ _r = _l->initcall_##level(); \
+ if (_r) { \
+ pr_warn("failed LSM %s %s initcall with errno %d\n", \
+ _l->id->name, #level, _r); \
+ if (!_rc) \
+ _rc = _r; \
+ } \
+ } \
+ _rc; \
+ })
+
/**
* lsm_choose_security - Legacy "major" LSM selection
* @str: kernel command line parameter
@@ -461,3 +482,71 @@ int __init security_init(void)
return 0;
}
+
+/**
+ * security_initcall_pure - Run the LSM pure initcalls
+ */
+static int __init security_initcall_pure(void)
+{
+ return lsm_initcall(pure);
+}
+pure_initcall(security_initcall_pure);
+
+/**
+ * security_initcall_early - Run the LSM early initcalls
+ */
+static int __init security_initcall_early(void)
+{
+ return lsm_initcall(early);
+}
+early_initcall(security_initcall_early);
+
+/**
+ * security_initcall_core - Run the LSM core initcalls
+ */
+static int __init security_initcall_core(void)
+{
+ return lsm_initcall(core);
+}
+core_initcall(security_initcall_core);
+
+/**
+ * security_initcall_subsys - Run the LSM subsys initcalls
+ */
+static int __init security_initcall_subsys(void)
+{
+ return lsm_initcall(subsys);
+}
+subsys_initcall(security_initcall_subsys);
+
+/**
+ * security_initcall_fs - Run the LSM fs initcalls
+ */
+static int __init security_initcall_fs(void)
+{
+ return lsm_initcall(fs);
+}
+fs_initcall(security_initcall_fs);
+
+/**
+ * security_initcall_device - Run the LSM device initcalls
+ */
+static int __init security_initcall_device(void)
+{
+ return lsm_initcall(device);
+}
+device_initcall(security_initcall_device);
+
+/**
+ * security_initcall_late - Run the LSM late initcalls
+ */
+static int __init security_initcall_late(void)
+{
+ int rc;
+
+ rc = lsm_initcall(late);
+ lsm_pr_dbg("all enabled LSMs fully activated\n");
+
+ return rc;
+}
+late_initcall(security_initcall_late);