[PATCH v2 2/5] rust: helpers: add C shims for LSM hook initialisation
Jamie Lindsey
jamie at matrixforgelabs.com
Wed Mar 11 05:09:04 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
Signed-off-by: Jamie Lindsey <jamie at matrixforgelabs.com>
---
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