[RFC PATCH 9/9] Loadpol LSM: add a minimal documentation
Paul Moore
paul at paul-moore.com
Wed May 21 21:31:18 UTC 2025
On Wed, May 21, 2025 at 10:03 AM Simon THOBY <git at nightmared.fr> wrote:
>
> Introduce a minimal documentation for Loadpol, presenting the policy
> format and the two user interfaces: the securityfs policy file and the
> sysctl.
>
> Signed-off-by: Simon THOBY <git at nightmared.fr>
> ---
> Documentation/admin-guide/LSM/Loadpol.rst | 81 +++++++++++++++++++++++
> Documentation/admin-guide/LSM/index.rst | 1 +
> 2 files changed, 82 insertions(+)
> create mode 100644 Documentation/admin-guide/LSM/Loadpol.rst
>
> diff --git a/Documentation/admin-guide/LSM/Loadpol.rst b/Documentation/admin-guide/LSM/Loadpol.rst
> new file mode 100644
> index 000000000000..0aa24a8d393c
> --- /dev/null
> +++ b/Documentation/admin-guide/LSM/Loadpol.rst
> @@ -0,0 +1,81 @@
> +.. SPDX-License-Identifier: GPL-2.0
> +
> +=======
> +Loadpol
> +=======
> +
> +Loadpol is a Linux Security Module that enforces a user-provided policy
> +when decided whether a dynamic module can be loaded or not.
Considering the relatively small scope of Loadpol, I have to ask if
you've considered augmenting other LSMs to meet your needs? While
LoadPin is different from what you are proposing here, it does
similarly limit its scope to kernel module load operations, and given
the current simplicity of LoadPin I imagine one could find a creative
way to extend it to support what you are trying to do.
> +The policy can be read and rewritten at ``/sys/kernel/security/loadpol/policy``.
> +
> +A default policy is created that contains the current list of blacklisted modules,
> +and a catch-all entry that allow loading any module.
> +
> +Policy format
> +=============
> +
> +The policy is defined as a set of line-separated entries.
> +Each entry define the conditions for a match (the origin of the load request and
> +the name of the kernel module), and the action to take when the load request
> +matches the entry.
> +
> +
> +Entry syntax: ``[origin=(userspace|kernel|kernel,userspace)] [module=<module_name>] action=(allow|deny)``
> +
> +There are two matching conditions:
> +
> +``origin``:
> + Load Requests can come from two origins:
> +
> + * ``userspace`` (ie. a program in userspace called modprobe/insmod)
> + * ``kernel`` (the kernel requested the module directly by calling
> + ``request_module(...)``, e.g. loading a filesystem when performing a
> + ``-o loop`` mount).
> +
> + When unspecified, the condition defaults to ``kernel,userspace`` (which means
> + that both origins match).
> +
> +``module``:
> + Name of the kernel module being matched. The name can contain wilcards.
> + Beware, module aliases do not work!
It would be good to have a section in the documentation where you
discuss how the risks inherent to filtering on the module name, and
approaches that can be used to ensure that a malicious module is not
simply "borrowing" a known good module's name.
> +There are two possible actions:
> +
> +* ``allow``: permit the load of the kernel module.
> +* ``deny``: reject the load of the kernel module and emit an audit log.
> +
> +The policy is not greedy: as soon as a match is found, the evaluation terminates
> +with the result of that match. So be very careful with the order of your entries.
> +
> +The main use cases of the policy will probably be to define an allowlist
> +(here, we allow ``module_a`` and any module starting with ``module_b`` loaded
> +by the user)::
> +
> + module==module_a action=allow
> + origin==user module==module_b* action=deny
> + action=deny
> +
> +But other mechanisms are possible, like a denylist
> +(here we block ``module_a``, ``module_b`` if it is loaded by the kernel and
> +any module starting with ``module_c`` loaded by the user)::
> +
> + module==module_a action=deny
> + origin==kernel module==module_b action=deny
> + origin==user module==module_c* action=deny
> + action=allow
> +
> +Policy lock
> +===========
> +
> +In order to protect the policy from tampering, a sysctl is provided to
> +lock-in-place the currently-loaded policy.
> +
> +The ``security.loadpol.locked`` can take 2 values:
> +
> +0 - default:
> + the policy can be reloaded at runtime by any administrator.
> +
> +1 - locked:
> + the policy cannot be updated or modified, and loadpol cannot be disabled
> + without rebooting.
> diff --git a/Documentation/admin-guide/LSM/index.rst b/Documentation/admin-guide/LSM/index.rst
> index b44ef68f6e4d..01d36670d8ad 100644
> --- a/Documentation/admin-guide/LSM/index.rst
> +++ b/Documentation/admin-guide/LSM/index.rst
> @@ -42,6 +42,7 @@ subdirectories.
>
> apparmor
> LoadPin
> + Loadpol
> SELinux
> Smack
> tomoyo
> --
> 2.49.0
--
paul-moore.com
More information about the Linux-security-module-archive
mailing list