[PATCH 2/5] rust: helpers: add C shims for LSM hook initialisation

Jamie Lindsey jamie at matrixforgelabs.com
Wed Mar 11 04:56:09 UTC 2026


struct security_hook_list carries __randomize_layout, making its fields
inaccessible to Rust code (bindgen sees the natural field order, which
may differ when CONFIG_RANDSTRUCT is active).  Add thin C wrapper
functions that call LSM_HOOK_INIT() — the existing C macro that handles
the randomised layout correctly — so that Rust can populate hook slots
without touching struct fields directly.

Three hook shims are provided (file_open, task_alloc, task_free) plus a
wrapper for security_add_hooks() which is __init and must carry that
annotation to ensure correct placement in the init text section.

Hook signatures verified against union security_list_options generated
from lsm_hook_defs.h: all three match exactly, including u64 for
task_alloc's clone_flags parameter (not unsigned long).

Assisted-by: Claude:claude-sonnet-4-6
---
 rust/helpers/helpers.c |  1 +
 rust/helpers/lsm.c     | 49 ++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 50 insertions(+)
 create mode 100644 rust/helpers/lsm.c

diff --git a/rust/helpers/helpers.c b/rust/helpers/helpers.c
index a3c42e51f00a..c496917be073 100644
--- a/rust/helpers/helpers.c
+++ b/rust/helpers/helpers.c
@@ -35,6 +35,7 @@
 #include "io.c"
 #include "jump_label.c"
 #include "kunit.c"
+#include "lsm.c"
 #include "maple_tree.c"
 #include "mm.c"
 #include "mutex.c"
diff --git a/rust/helpers/lsm.c b/rust/helpers/lsm.c
new file mode 100644
index 000000000000..fb475428fd0d
--- /dev/null
+++ b/rust/helpers/lsm.c
@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: GPL-2.0
+
+#include <linux/lsm_hooks.h>
+
+/*
+ * Hook list initializers.
+ *
+ * struct security_hook_list carries __randomize_layout, so its fields must
+ * never be set by Rust code directly (bindgen sees only the "natural" field
+ * order, which may differ when CONFIG_RANDSTRUCT is enabled).  These helpers
+ * wrap LSM_HOOK_INIT(), the C macro the kernel already uses for this purpose,
+ * so that Rust can safely obtain an initialised security_hook_list without
+ * ever touching the struct's fields directly.
+ */
+
+__rust_helper void
+rust_helper_lsm_hook_init_file_open(struct security_hook_list *hl,
+				    int (*fn)(struct file *))
+{
+	*hl = (struct security_hook_list)LSM_HOOK_INIT(file_open, fn);
+}
+
+__rust_helper void
+rust_helper_lsm_hook_init_task_alloc(struct security_hook_list *hl,
+				     int (*fn)(struct task_struct *, u64))
+{
+	*hl = (struct security_hook_list)LSM_HOOK_INIT(task_alloc, fn);
+}
+
+__rust_helper void
+rust_helper_lsm_hook_init_task_free(struct security_hook_list *hl,
+				    void (*fn)(struct task_struct *))
+{
+	*hl = (struct security_hook_list)LSM_HOOK_INIT(task_free, fn);
+}
+
+/*
+ * security_add_hooks() is __init — it installs callbacks into the static-call
+ * table and must only be called during kernel initialisation.  This wrapper
+ * keeps the __init annotation so the linker places it alongside the rest of
+ * the init text, and Rust callers invoke it only from their own __init path
+ * (the lsm_info.init callback).
+ */
+void __init
+rust_helper_security_add_hooks(struct security_hook_list *hooks, int count,
+			       const struct lsm_id *lsmid)
+{
+	security_add_hooks(hooks, count, lsmid);
+}
-- 
2.53.0




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