All of lore.kernel.org
 help / color / mirror / Atom feed
From: Ian Bridges <icb@fastmail.org>
To: Paul Moore <paul@paul-moore.com>,
	Stephen Smalley <stephen.smalley.work@gmail.com>,
	Ondrej Mosnacek <omosnace@redhat.com>
Cc: selinux@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [PATCH] selinux: compute the IMA configuration settings string length once at boot
Date: Mon, 13 Jul 2026 23:09:54 -0500	[thread overview]
Message-ID: <alW2ktr8JUVlQNgU@dev> (raw)

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 <paul@paul-moore.com>
Link: https://lore.kernel.org/r/df755e0282dab3b932d19aceab71b7d7@paul-moore.com
Signed-off-by: Ian Bridges <icb@fastmail.org>
---
The produced string is unchanged. selinux_ima_collect_state() now
depends on selinux_ima_config_len_init() having run. The call sits in
selinux_init(), as suggested in the review of the seq_buf conversion.

The length computation itself moves verbatim. The strlen() + 1 on
the string literal could become sizeof(), which counts the
terminator. That rewrite was left out so the moved block stays
identical to the applied code.

The patch was tested as follows.

- W=1 build of security/selinux with CONFIG_IMA=y, zero warnings.
- A userspace differential harness compiled the old and the new
  functions side by side, covering every combination of the settings
  and the policy capabilities. The outputs were byte identical. The
  stored length was an exact fit for the produced string in every
  case, with no overflow and no slack.

 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)
 {
 }
-- 
2.47.3


                 reply	other threads:[~2026-07-14  4:09 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

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=alW2ktr8JUVlQNgU@dev \
    --to=icb@fastmail.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=omosnace@redhat.com \
    --cc=paul@paul-moore.com \
    --cc=selinux@vger.kernel.org \
    --cc=stephen.smalley.work@gmail.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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.