From: Michal Gorlas <hidden> Date: 2026-05-15 17:20:36
Add option to restrict the module auto-loading to CAP_SYS_ADMIN.
This is heavily inspired by CONFIG_GRKERNSEC_MODHARDEN of the latest
available Grsecurity patches [1]. Instead of checking whether the
callers' UID is 0, check whether the calling process has CAP_SYS_ADMIN.
The reasoning here is that many modules are autoloaded by systemd
services which are running as privileged users, but do not have UID 0.
While systemd-udevd runs as root, systemd-network (which often
auto-loads a module) for example runs as system user (UID range 6 to
999).
When enabled, reduces attack surface where unprivileged users can trigger
vulnerable module to be auto-loaded, to then exploit it. Recent LPEs
(CopyFail [3], DirtyFrag [4]) for example, would have been mitigated
with this option enabled as long as the vulnerable modules are not built-in
(or already loaded at the point of running the exploit).
[1] - https://github.com/minipli/linux-unofficial_grsec/blob/linux-4.9.x-unofficial_grsec/kernel/kmod.c#L153
[2] - https://systemd.io/UIDS-GIDS/
[3] - https://github.com/theori-io/copy-fail-CVE-2026-31431
[4] - https://github.com/V4bel/dirtyfrag
Signed-off-by: Michal Gorlas <redacted>
---
Michal Gorlas (2):
module: add CONFIG_MODULE_RESTRICT_AUTOLOAD
module: restrict autoload to CAP_SYS_ADMIN if CONFIG_MODULE_RESTRICT_AUTOLOAD
Documentation/admin-guide/kernel-parameters.txt | 5 +++++
kernel/module/Kconfig | 15 +++++++++++++++
kernel/module/internal.h | 1 +
kernel/module/kmod.c | 5 +++++
kernel/module/main.c | 11 +++++++++++
5 files changed, 37 insertions(+)
---
base-commit: 663385f9155f27892a97a5824006f806a32eb8dc
change-id: 20260515-autoload_restrict-cfa6727c4d72
Best regards,
--
Michal Gorlas [off-list ref]
@@ -4185,6 +4185,11 @@ Kernel parameters For details see: Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst+ modrestrict=<bool>+ Control the restriction of module auto-loading to+ CAP_SYS_ADMIN. If no <bool> value is specified, this+ is set to the value of CONFIG_MODULE_RESTRICT_AUTOLOAD.+ <module>.async_probe[=<bool>] [KNL] If no <bool> value is specified or if the value specified is not a valid <bool>, enable asynchronous
From: Michal Gorlas <hidden> Date: 2026-05-15 17:20:38
Restrict module auto-loading to CAP_SYS_ADMIN if
CONFIG_MODULE_RESTRICT_AUTOLOAD is enabled, cmdline parameter
modrestrict=true, or kernel.modrestrict=1 is set with sysctl.
Signed-off-by: Michal Gorlas <redacted>
---
kernel/module/internal.h | 1 +
kernel/module/kmod.c | 5 +++++
kernel/module/main.c | 11 +++++++++++
3 files changed, 17 insertions(+)
@@ -156,6 +156,11 @@ int __request_module(bool wait, const char *fmt, ...)if(ret)returnret;+if(module_autoload_restrict&&!capable(CAP_SYS_ADMIN)){+pr_alert("denied attempt to auto-load module %s\n",module_name);+return-EPERM;+}+ret=down_timeout(&kmod_concurrent_max,MAX_KMOD_ALL_BUSY_TIMEOUT*HZ);if(ret){pr_warn_ratelimited("request_module: modprobe %s cannot be processed, kmod busy with %d threads for more than %d seconds now",
+ can abuse auto-loading to cause a vulnerable module to load that is+ then exploited.++ Note that this option also prevents a benign use of auto-loading for+ a non-root users. Thus if enabled, the root user should execute+ modprobe manually if needed, or add the module to the list of modules+ loaded at the boot by modifying init scripts.
@@ -4185,6 +4185,11 @@ Kernel parameters For details see: Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst+ modrestrict=<bool>+ Control the restriction of module auto-loading to+ CAP_SYS_ADMIN. If no <bool> value is specified, this+ is set to the value of CONFIG_MODULE_RESTRICT_AUTOLOAD.
Doesn't this default to true if no bool value is specified? It only uses
the config if modrestrict is not passed to the kernel at all.
quoted hunk
<module>.async_probe[=<bool>] [KNL]
If no <bool> value is specified or if the value
specified is not a valid <bool>, enable asynchronous
You don't need to specify default n here.
Also, I think you can just squash the two patches. There's no benefit
in splitting the config/documentation into a separate patch.
Sami
From: Sami Tolvanen <samitolvanen@google.com> Date: 2026-06-05 18:30:08
On Fri, May 15, 2026 at 07:20:20PM +0200, Michal Gorlas wrote:
quoted hunk
Restrict module auto-loading to CAP_SYS_ADMIN if
CONFIG_MODULE_RESTRICT_AUTOLOAD is enabled, cmdline parameter
modrestrict=true, or kernel.modrestrict=1 is set with sysctl.
Signed-off-by: Michal Gorlas <redacted>
---
kernel/module/internal.h | 1 +
kernel/module/kmod.c | 5 +++++
kernel/module/main.c | 11 +++++++++++
3 files changed, 17 insertions(+)
From: Sami Tolvanen <samitolvanen@google.com> Date: 2026-06-05 18:36:52
On Fri, May 15, 2026 at 07:20:18PM +0200, Michal Gorlas wrote:
Add option to restrict the module auto-loading to CAP_SYS_ADMIN.
This is heavily inspired by CONFIG_GRKERNSEC_MODHARDEN of the latest
available Grsecurity patches [1]. Instead of checking whether the
callers' UID is 0, check whether the calling process has CAP_SYS_ADMIN.
The reasoning here is that many modules are autoloaded by systemd
services which are running as privileged users, but do not have UID 0.
While systemd-udevd runs as root, systemd-network (which often
auto-loads a module) for example runs as system user (UID range 6 to
999).
When enabled, reduces attack surface where unprivileged users can trigger
vulnerable module to be auto-loaded, to then exploit it. Recent LPEs
(CopyFail [3], DirtyFrag [4]) for example, would have been mitigated
with this option enabled as long as the vulnerable modules are not built-in
(or already loaded at the point of running the exploit).
This sounds potentially useful as an optional feature. Kees, you've
looked at grsec features in the past, do you have any thoughts about
this?
Sami
@@ -4185,6 +4185,11 @@ Kernel parameters For details see: Documentation/admin-guide/hw-vuln/processor_mmio_stale_data.rst+ modrestrict=<bool>+ Control the restriction of module auto-loading to+ CAP_SYS_ADMIN. If no <bool> value is specified, this+ is set to the value of CONFIG_MODULE_RESTRICT_AUTOLOAD.
Doesn't this default to true if no bool value is specified? It only uses
the config if modrestrict is not passed to the kernel at all.
Right. Will adjust the description here.
quoted
<module>.async_probe[=<bool>] [KNL]
If no <bool> value is specified or if the value
specified is not a valid <bool>, enable asynchronous
You don't need to specify default n here.
Also, I think you can just squash the two patches. There's no benefit
in splitting the config/documentation into a separate patch.
From: Michal Gorlas <hidden> Date: 2026-06-09 10:19:03
On Fri Jun 5, 2026 at 8:30 PM CEST, Sami Tolvanen wrote:
On Fri, May 15, 2026 at 07:20:20PM +0200, Michal Gorlas wrote:
quoted
Restrict module auto-loading to CAP_SYS_ADMIN if
CONFIG_MODULE_RESTRICT_AUTOLOAD is enabled, cmdline parameter
modrestrict=true, or kernel.modrestrict=1 is set with sysctl.
Signed-off-by: Michal Gorlas <redacted>
---
kernel/module/internal.h | 1 +
kernel/module/kmod.c | 5 +++++
kernel/module/main.c | 11 +++++++++++
3 files changed, 17 insertions(+)
On Fri, Jun 05, 2026 at 06:36:46PM +0000, Sami Tolvanen wrote:
On Fri, May 15, 2026 at 07:20:18PM +0200, Michal Gorlas wrote:
quoted
Add option to restrict the module auto-loading to CAP_SYS_ADMIN.
This is heavily inspired by CONFIG_GRKERNSEC_MODHARDEN of the latest
available Grsecurity patches [1]. Instead of checking whether the
callers' UID is 0, check whether the calling process has CAP_SYS_ADMIN.
The reasoning here is that many modules are autoloaded by systemd
services which are running as privileged users, but do not have UID 0.
While systemd-udevd runs as root, systemd-network (which often
auto-loads a module) for example runs as system user (UID range 6 to
999).
When enabled, reduces attack surface where unprivileged users can trigger
vulnerable module to be auto-loaded, to then exploit it. Recent LPEs
(CopyFail [3], DirtyFrag [4]) for example, would have been mitigated
with this option enabled as long as the vulnerable modules are not built-in
(or already loaded at the point of running the exploit).
This sounds potentially useful as an optional feature. Kees, you've
looked at grsec features in the past, do you have any thoughts about
this?
This doesn't really look like GRKERNSEC_MODHARDEN to me? In that
feature, the credentials of the usermode helper are passed down so that
udev or whatever can examine them and make choices (instead of seeing
the uid-0 usermode helper credentials).
This looks like it is just doing a request-time policy check, but that's
already covered by the security_kernel_module_request() call immediately
before the proposed module_autoload_restrict check.
Also note that module loading is _already_ controlled by CAP_SYS_MODULE,
not uid 0 nor CAP_SYS_ADMIN.
Sashiko has similar feedback, and some other notes too:
https://sashiko.dev/#/patchset/20260515-autoload_restrict-v1-0-40b7c03ddd04%409elements.com
I'm not clear what problem this patch is trying to solve?
-Kees
--
Kees Cook
From: Michal Gorlas <hidden> Date: 2026-06-12 12:41:51
On Wed Jun 10, 2026 at 10:23 PM CEST, Kees Cook wrote:
On Fri, Jun 05, 2026 at 06:36:46PM +0000, Sami Tolvanen wrote:
quoted
On Fri, May 15, 2026 at 07:20:18PM +0200, Michal Gorlas wrote:
quoted
Add option to restrict the module auto-loading to CAP_SYS_ADMIN.
This is heavily inspired by CONFIG_GRKERNSEC_MODHARDEN of the latest
available Grsecurity patches [1]. Instead of checking whether the
callers' UID is 0, check whether the calling process has CAP_SYS_ADMIN.
The reasoning here is that many modules are autoloaded by systemd
services which are running as privileged users, but do not have UID 0.
While systemd-udevd runs as root, systemd-network (which often
auto-loads a module) for example runs as system user (UID range 6 to
999).
When enabled, reduces attack surface where unprivileged users can trigger
vulnerable module to be auto-loaded, to then exploit it. Recent LPEs
(CopyFail [3], DirtyFrag [4]) for example, would have been mitigated
with this option enabled as long as the vulnerable modules are not built-in
(or already loaded at the point of running the exploit).
This sounds potentially useful as an optional feature. Kees, you've
looked at grsec features in the past, do you have any thoughts about
this?
This doesn't really look like GRKERNSEC_MODHARDEN to me? In that
feature, the credentials of the usermode helper are passed down so that
udev or whatever can examine them and make choices (instead of seeing
the uid-0 usermode helper credentials).
It is based on a part of GRKERNSEC_MODHARDEN policy check in
____request_module in [1]. By no means it reasembles the full
feature. Very similar check was proposed for linux-hardened
tree few years back (with the difference of checking for
CAP_SYS_MODULE) [2].
This looks like it is just doing a request-time policy check, but that's
already covered by the security_kernel_module_request() call immediately
before the proposed module_autoload_restrict check.
Also note that module loading is _already_ controlled by CAP_SYS_MODULE,
not uid 0 nor CAP_SYS_ADMIN.
Sashiko has similar feedback, and some other notes too:
https://sashiko.dev/#/patchset/20260515-autoload_restrict-v1-0-40b7c03ddd04%409elements.com
My understanding is that CAP_SYS_MODULE is for processes that are
using load/unload directly (i.e. by doing init_module/delete_module
syscall), and the kmod's__request_module, is a user mode call
(at least that's what the comment in __request_module suggests),
so CAP_SYS_MODULE does not have to be set for processes that are
just using __request_module. One example of this is systemd-networkd
(there are probably more but that's one that I tested), i.e. it will
trigger the module autoload even though its not given CAP_SYS_MODULE.
Please correct me if I am wrong here.
I'm not clear what problem this patch is trying to solve?