[PATCH 5/5] Documentation: rust: add LSM abstraction guide; update MAINTAINERS
Jamie Lindsey
jamie at matrixforgelabs.com
Wed Mar 11 04:56:13 UTC 2026
Add Documentation/rust/lsm.rst, a developer guide for writing Linux
Security Modules in Rust using the kernel::lsm abstraction layer.
Covers:
- The Hooks trait: per-hook semantics, return values, sleeping rules.
- The define_lsm! macro: arguments and what it generates.
- Kconfig and Makefile wiring patterns.
- lsm_count.h: how to update MAX_LSM_COUNT for new built-in LSMs.
- A complete minimal example.
- Boot activation via lsm= and CONFIG_LSM.
- v1 limitations (three hooks, one Rust LSM per build, no blob support).
- C headers of interest for LSM authors.
Link the new document from Documentation/rust/index.rst.
Add a MAINTAINERS entry (RUST LSM ABSTRACTIONS) covering:
rust/helpers/lsm.c, rust/kernel/lsm.rs, security/rust_lsm/
Listed on both rust-for-linux at vger.kernel.org and
linux-security-module at vger.kernel.org.
Assisted-by: Claude:claude-sonnet-4-6
---
Documentation/rust/index.rst | 1 +
Documentation/rust/lsm.rst | 246 +++++++++++++++++++++++++++++++++++
MAINTAINERS | 9 ++
3 files changed, 256 insertions(+)
create mode 100644 Documentation/rust/lsm.rst
diff --git a/Documentation/rust/index.rst b/Documentation/rust/index.rst
index b78ed0efa784..a4cb4bf8faf2 100644
--- a/Documentation/rust/index.rst
+++ b/Documentation/rust/index.rst
@@ -37,6 +37,7 @@ more details.
coding-guidelines
arch-support
testing
+ lsm
You can also find learning materials for Rust in its section in
:doc:`../process/kernel-docs`.
diff --git a/Documentation/rust/lsm.rst b/Documentation/rust/lsm.rst
new file mode 100644
index 000000000000..c4e16e7d2be5
--- /dev/null
+++ b/Documentation/rust/lsm.rst
@@ -0,0 +1,246 @@
+.. SPDX-License-Identifier: GPL-2.0
+
+Linux Security Modules in Rust
+================================
+
+This document describes how to write a Linux Security Module (LSM) using
+the Rust abstractions provided in ``rust/kernel/lsm.rs``.
+
+
+Overview
+--------
+
+The LSM framework allows security policies to be implemented as kernel
+modules that register hooks into security-sensitive operations. Traditionally
+these are written in C; the Rust abstraction layer provides a safe,
+trait-based interface that enforces correct hook registration at compile time.
+
+A Rust LSM:
+
+1. Implements the :ref:`Hooks trait <rust_lsm_hooks_trait>` for the subset
+ of hooks it cares about.
+2. Registers itself at boot time using the :ref:`define_lsm! macro
+ <rust_lsm_define_macro>`.
+
+No C code is required by the LSM author. The abstraction layer generates
+the necessary C-callable adapter functions and places the ``lsm_info``
+descriptor in the ``.lsm_info.init`` ELF section, where
+``security_init()`` discovers it during boot.
+
+
+.. _rust_lsm_hooks_trait:
+
+The ``Hooks`` trait
+-------------------
+
+``kernel::lsm::Hooks`` is the central trait. Each method corresponds to one
+LSM hook. All methods have a default no-op implementation, so an implementor
+only needs to override the hooks it cares about::
+
+ pub trait Hooks: Sync + Send + 'static {
+ fn file_open(_file: &File) -> Result { Ok(()) }
+ fn task_alloc(_task: &Task, _clone_flags: u64) -> Result { Ok(()) }
+ fn task_free(_task: &Task) {}
+ }
+
+The ``Sync + Send + 'static`` bounds are required because hook functions may
+be called concurrently from any CPU.
+
+Return values
+~~~~~~~~~~~~~
+
+Hooks that can deny an operation return ``kernel::error::Result``:
+
+- ``Ok(())`` — allow the operation.
+- ``Err(e)`` — deny the operation; ``e.to_errno()`` is returned to the caller.
+
+Common denial error codes:
+
+- ``EACCES`` — permission denied (policy decision).
+- ``EPERM`` — operation not permitted (capability check).
+
+The ``task_free`` hook cannot deny anything and has no return value.
+
+Sleeping
+~~~~~~~~
+
+``task_free`` is called in a non-sleeping context. Implementations **must
+not** sleep or allocate memory with ``GFP_KERNEL`` inside ``task_free``.
+All other hooks may sleep unless the call site is documented otherwise.
+
+
+Available hooks (v1)
+~~~~~~~~~~~~~~~~~~~~~
+
+.. list-table::
+ :widths: 25 75
+ :header-rows: 1
+
+ * - Hook
+ - When called
+ * - ``file_open``
+ - A file is being opened. Return ``Err`` to deny the open.
+ * - ``task_alloc``
+ - A new task (thread or process) is being created via ``clone(2)``
+ or ``fork(2)``. ``clone_flags`` contains the ``CLONE_*`` flags.
+ Return ``Err`` to deny creation.
+ * - ``task_free``
+ - A task is being freed. Must not sleep. Use this to clean up any
+ per-task state associated with the LSM.
+
+
+.. _rust_lsm_define_macro:
+
+The ``define_lsm!`` macro
+--------------------------
+
+``kernel::define_lsm!`` registers a type implementing ``Hooks`` with the
+kernel LSM framework::
+
+ kernel::define_lsm!(MyLsmType, "my_lsm\0", bindings::LSM_ID_UNDEF as u64);
+
+Arguments:
+
+.. list-table::
+ :widths: 20 80
+ :header-rows: 1
+
+ * - Argument
+ - Description
+ * - ``$T``
+ - The type implementing ``Hooks``. Must be ``Sync + Send + 'static``.
+ * - ``$name``
+ - A ``&str`` literal with a NUL terminator (``\0``). This name is used
+ in ``/sys/kernel/security/lsm`` and in the ``lsm=`` kernel command-line
+ parameter.
+ * - ``$id``
+ - The LSM identity constant from ``include/uapi/linux/lsm.h``. Use
+ ``bindings::LSM_ID_UNDEF as u64`` during development; request a
+ permanent value as part of the upstream patch series.
+
+The macro generates:
+
+- A ``static __LSM_ID: LsmId`` holding the LSM identity.
+- A ``static mut __LSM_HOOKS`` array of ``MaybeUninit<security_hook_list>``
+ entries, one per registered hook.
+- An ``unsafe extern "C" fn __lsm_init()`` that fills each hook slot using
+ the C ``LSM_HOOK_INIT`` shim (necessary because ``security_hook_list`` has
+ ``__randomize_layout``) and calls ``security_add_hooks()``.
+- A ``static __LSM_INFO: LsmInfo`` in the ``.lsm_info.init`` ELF section,
+ which ``security_init()`` iterates at boot to discover and call the init
+ function.
+
+
+Enabling in Kconfig
+-------------------
+
+To include a Rust LSM in the build, add a ``Kconfig`` entry that selects
+``RUST`` and depends on ``SECURITY``::
+
+ config SECURITY_MY_LSM
+ bool "My Rust LSM"
+ depends on SECURITY
+ select RUST
+ help
+ A minimal Rust LSM that ...
+
+Wire the object into the build in ``security/Makefile``::
+
+ obj-$(CONFIG_SECURITY_MY_LSM) += my_lsm/
+
+And in ``security/my_lsm/Makefile``::
+
+ obj-$(CONFIG_SECURITY_MY_LSM) += my_lsm.o
+
+The source file must **not** declare ``#![no_std]`` — the build system injects
+it automatically for all kernel Rust objects.
+
+Define ``__LOG_PREFIX`` at the top of the source file so that ``pr_info!`` and
+friends work correctly::
+
+ const __LOG_PREFIX: &[u8] = b"my_lsm\0";
+
+
+Minimal example
+---------------
+
+The following is a complete, minimal Rust LSM that logs every file open and
+allows all operations::
+
+ // SPDX-License-Identifier: GPL-2.0
+
+ //! Minimal Rust LSM example.
+
+ const __LOG_PREFIX: &[u8] = b"my_lsm\0";
+
+ use kernel::bindings;
+ use kernel::lsm;
+ use kernel::prelude::*;
+
+ struct MyLsm;
+
+ impl lsm::Hooks for MyLsm {
+ fn file_open(file: &kernel::fs::File) -> Result {
+ pr_info!("file_open: flags={:#x}\n", file.flags());
+ Ok(())
+ }
+ }
+
+ kernel::define_lsm!(MyLsm, "my_lsm\0", bindings::LSM_ID_UNDEF as u64);
+
+The reference implementation is at ``security/rust_lsm/rust_lsm.rs``
+(``CONFIG_SECURITY_RUST_LSM``).
+
+
+Activating at boot
+------------------
+
+A Rust LSM compiled into the kernel is activated by listing its name in the
+``lsm=`` kernel command-line parameter or by adding it to the ``CONFIG_LSM``
+Kconfig string.
+
+The LSM name must also be counted in ``include/linux/lsm_count.h`` so that
+``MAX_LSM_COUNT`` is large enough to accommodate it alongside other compiled-in
+LSMs. Add a ``CONFIG_SECURITY_MY_LSM``-guarded macro alongside the existing
+entries::
+
+ #ifdef CONFIG_SECURITY_MY_LSM
+ #define MY_LSM_ENABLED 1,
+ #else
+ #define MY_LSM_ENABLED
+ #endif
+
+ #define MAX_LSM_COUNT \
+ COUNT_LSMS( \
+ ...existing entries... \
+ MY_LSM_ENABLED)
+
+To verify the LSM is active after boot::
+
+ cat /sys/kernel/security/lsm
+
+
+Limitations (v1)
+-----------------
+
+- Only three hooks are available: ``file_open``, ``task_alloc``, and
+ ``task_free``. Additional hooks will be added in follow-up patches as safe
+ Rust wrappers for their argument types are contributed upstream.
+
+- At most one Rust LSM can be registered per kernel build with the current
+ macro design. Supporting multiple Rust LSMs requires unique static symbol
+ generation, planned for v2 using a proc-macro.
+
+- No security blob support. Per-task or per-inode data associated with a
+ Rust LSM requires the ``SecurityBlob<T>`` abstraction planned for v2.
+
+
+C headers of interest
+---------------------
+
+- ``include/linux/lsm_hooks.h`` — ``lsm_info``, ``security_hook_list``,
+ ``LSM_HOOK_INIT``, ``LSM_ORDER_*``.
+- ``include/linux/lsm_hook_defs.h`` — canonical hook signatures.
+- ``include/uapi/linux/lsm.h`` — ``LSM_ID_*`` constants.
+- ``include/linux/lsm_count.h`` — ``MAX_LSM_COUNT`` computation.
+- ``security/security.c`` — ``security_init()``, ``security_add_hooks()``.
diff --git a/MAINTAINERS b/MAINTAINERS
index 89007f9ed35e..a23f5a15e038 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -23196,6 +23196,15 @@ S: Maintained
T: git https://github.com/Rust-for-Linux/linux.git rust-analyzer-next
F: scripts/generate_rust_analyzer.py
+RUST LSM ABSTRACTIONS
+M: Jamie Lindsey <jamie at matrixforgelabs.com>
+L: rust-for-linux at vger.kernel.org
+L: linux-security-module at vger.kernel.org
+S: Maintained
+F: rust/helpers/lsm.c
+F: rust/kernel/lsm.rs
+F: security/rust_lsm/
+
RXRPC SOCKETS (AF_RXRPC)
M: David Howells <dhowells at redhat.com>
M: Marc Dionne <marc.dionne at auristor.com>
--
2.53.0
More information about the Linux-security-module-archive
mailing list