From c0b6a5b89d1aa31574ea68bfb1fed1dee46e5ec6 Mon Sep 17 00:00:00 2001 From: Ian Bridges Date: Mon, 13 Jul 2026 23:09:54 -0500 Subject: [PATCH] selinux: compute the IMA configuration settings string length once at boot selinux_ima_collect_state() builds a string of the current SELinux configuration settings. The string lists each setting as a name and one digit. The length of the string therefore never changes, but is still recomputed on every call. Add selinux_ima_config_len_init() to compute the length once during selinux_init(). Update selinux_ima_collect_state() to use the stored length. Suggested-by: Paul Moore Link: https://lore.kernel.org/r/df755e0282dab3b932d19aceab71b7d7@paul-moore.com Signed-off-by: Ian Bridges Reviewed-by: Stephen Smalley Signed-off-by: Paul Moore --- security/selinux/hooks.c | 3 +++ security/selinux/ima.c | 33 ++++++++++++++++++++++++--------- security/selinux/include/ima.h | 4 ++++ 3 files changed, 31 insertions(+), 9 deletions(-) diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c index f4a4edbff2bd..1ead2eee1944 100644 --- a/security/selinux/hooks.c +++ b/security/selinux/hooks.c @@ -107,6 +107,7 @@ #include "netlabel.h" #include "audit.h" #include "avc_ss.h" +#include "ima.h" #define SELINUX_INODE_INIT_XATTRS 1 @@ -7856,6 +7857,8 @@ static __init int selinux_init(void) hashtab_cache_init(); + selinux_ima_config_len_init(); + security_add_hooks(selinux_hooks, ARRAY_SIZE(selinux_hooks), &selinux_lsmid); diff --git a/security/selinux/ima.c b/security/selinux/ima.c index cb0efa2fc1ad..cda68122e032 100644 --- a/security/selinux/ima.c +++ b/security/selinux/ima.c @@ -13,6 +13,27 @@ #include "security.h" #include "ima.h" +static int selinux_ima_config_len __ro_after_init; + +/* + * selinux_ima_config_len_init - Compute the configuration settings string length + * + * The string is fixed text plus one digit per setting, so its length + * is known at boot. + */ +void __init selinux_ima_config_len_init(void) +{ + int buf_len, suffix_len, i; + + buf_len = strlen("initialized=0;enforcing=0;checkreqprot=0;") + 1; + suffix_len = strlen("=0;"); + + for (i = 0; i < __POLICYDB_CAP_MAX; i++) + buf_len += strlen(selinux_policycap_names[i]) + suffix_len; + + selinux_ima_config_len = buf_len; +} + /* * selinux_ima_collect_state - Read selinux configuration settings * @@ -23,19 +44,13 @@ static char *selinux_ima_collect_state(void) { struct seq_buf s; char *buf; - int buf_len, suffix_len, i; + int i; - buf_len = strlen("initialized=0;enforcing=0;checkreqprot=0;") + 1; - suffix_len = strlen("=0;"); - - for (i = 0; i < __POLICYDB_CAP_MAX; i++) - buf_len += strlen(selinux_policycap_names[i]) + suffix_len; - - buf = kzalloc(buf_len, GFP_KERNEL); + buf = kzalloc(selinux_ima_config_len, GFP_KERNEL); if (!buf) return NULL; - seq_buf_init(&s, buf, buf_len); + seq_buf_init(&s, buf, selinux_ima_config_len); seq_buf_printf(&s, "initialized=%d;enforcing=%d;checkreqprot=%d;", selinux_initialized(), enforcing_enabled(), diff --git a/security/selinux/include/ima.h b/security/selinux/include/ima.h index 38ab302f5946..d7d18f030d3d 100644 --- a/security/selinux/include/ima.h +++ b/security/selinux/include/ima.h @@ -14,9 +14,13 @@ #include "security.h" #ifdef CONFIG_IMA +void __init selinux_ima_config_len_init(void); extern void selinux_ima_measure_state(void); extern void selinux_ima_measure_state_locked(void); #else +static inline void selinux_ima_config_len_init(void) +{ +} static inline void selinux_ima_measure_state(void) { }