Linux Documentation
 help / color / mirror / Atom feed
* [PATCH 0/2] module: restrict module auto-loading to privileged users
@ 2026-05-15 17:20 Michal Gorlas
  2026-05-15 17:20 ` [PATCH 1/2] module: add CONFIG_MODULE_RESTRICT_AUTOLOAD Michal Gorlas
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Michal Gorlas @ 2026-05-15 17:20 UTC (permalink / raw)
  To: Jonathan Corbet, Shuah Khan, Luis Chamberlain, Petr Pavlu,
	Daniel Gomez, Sami Tolvanen, Aaron Tomlin
  Cc: linux-doc, linux-kernel, linux-modules, Michal Gorlas

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 <michal.gorlas@9elements.com>
---
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 <michal.gorlas@9elements.com>


^ permalink raw reply	[flat|nested] 7+ messages in thread

* [PATCH 1/2] module: add CONFIG_MODULE_RESTRICT_AUTOLOAD
  2026-05-15 17:20 [PATCH 0/2] module: restrict module auto-loading to privileged users Michal Gorlas
@ 2026-05-15 17:20 ` Michal Gorlas
  2026-05-16  3:03   ` Randy Dunlap
  2026-06-05 18:25   ` Sami Tolvanen
  2026-05-15 17:20 ` [PATCH 2/2] module: restrict autoload to CAP_SYS_ADMIN if CONFIG_MODULE_RESTRICT_AUTOLOAD Michal Gorlas
  2026-06-05 18:36 ` [PATCH 0/2] module: restrict module auto-loading to privileged users Sami Tolvanen
  2 siblings, 2 replies; 7+ messages in thread
From: Michal Gorlas @ 2026-05-15 17:20 UTC (permalink / raw)
  To: Jonathan Corbet, Shuah Khan, Luis Chamberlain, Petr Pavlu,
	Daniel Gomez, Sami Tolvanen, Aaron Tomlin
  Cc: linux-doc, linux-kernel, linux-modules, Michal Gorlas

Add CONFIG_MODULE_RESTRICT_AUTOLOAD and modrestrict parameter
documentation.

Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
---
 Documentation/admin-guide/kernel-parameters.txt |  5 +++++
 kernel/module/Kconfig                           | 15 +++++++++++++++
 2 files changed, 20 insertions(+)

diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index 03a550630644..1013104f0943 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -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
diff --git a/kernel/module/Kconfig b/kernel/module/Kconfig
index 43b1bb01fd27..c9e01bb848c0 100644
--- a/kernel/module/Kconfig
+++ b/kernel/module/Kconfig
@@ -337,6 +337,21 @@ config MODULE_SIG_HASH
 
 endif # MODULE_SIG || IMA_APPRAISE_MODSIG
 
+config MODULE_RESTRICT_AUTOLOAD
+	bool "Restrict module auto-loading to privileged users"
+	default n
+	help
+	  Restrict module auto-loading in response to use of some feature
+	  implemented by an unloaded module to CAP_SYS_ADMIN. Enabling this
+	  option helps reducing the attack surface where unprivileged users
+	  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.
+
 config MODULE_COMPRESS
 	bool "Module compression"
 	help

-- 
2.54.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* [PATCH 2/2] module: restrict autoload to CAP_SYS_ADMIN if CONFIG_MODULE_RESTRICT_AUTOLOAD
  2026-05-15 17:20 [PATCH 0/2] module: restrict module auto-loading to privileged users Michal Gorlas
  2026-05-15 17:20 ` [PATCH 1/2] module: add CONFIG_MODULE_RESTRICT_AUTOLOAD Michal Gorlas
@ 2026-05-15 17:20 ` Michal Gorlas
  2026-06-05 18:30   ` Sami Tolvanen
  2026-06-05 18:36 ` [PATCH 0/2] module: restrict module auto-loading to privileged users Sami Tolvanen
  2 siblings, 1 reply; 7+ messages in thread
From: Michal Gorlas @ 2026-05-15 17:20 UTC (permalink / raw)
  To: Jonathan Corbet, Shuah Khan, Luis Chamberlain, Petr Pavlu,
	Daniel Gomez, Sami Tolvanen, Aaron Tomlin
  Cc: linux-doc, linux-kernel, linux-modules, Michal Gorlas

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 <michal.gorlas@9elements.com>
---
 kernel/module/internal.h |  1 +
 kernel/module/kmod.c     |  5 +++++
 kernel/module/main.c     | 11 +++++++++++
 3 files changed, 17 insertions(+)

diff --git a/kernel/module/internal.h b/kernel/module/internal.h
index 061161cc79d9..496d8703f0c6 100644
--- a/kernel/module/internal.h
+++ b/kernel/module/internal.h
@@ -46,6 +46,7 @@ struct kernel_symbol {
 
 extern struct mutex module_mutex;
 extern struct list_head modules;
+extern bool module_autoload_restrict;
 
 extern const struct module_attribute *const modinfo_attrs[];
 extern const size_t modinfo_attrs_count;
diff --git a/kernel/module/kmod.c b/kernel/module/kmod.c
index a25dccdf7aa7..58b28c23f571 100644
--- a/kernel/module/kmod.c
+++ b/kernel/module/kmod.c
@@ -156,6 +156,11 @@ int __request_module(bool wait, const char *fmt, ...)
 	if (ret)
 		return ret;
 
+	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",
diff --git a/kernel/module/main.c b/kernel/module/main.c
index 46dd8d25a605..a293b75ce9b7 100644
--- a/kernel/module/main.c
+++ b/kernel/module/main.c
@@ -130,6 +130,10 @@ static void mod_update_bounds(struct module *mod)
 static int modules_disabled;
 core_param(nomodule, modules_disabled, bint, 0);
 
+/* Restrict auto-loading? */
+bool module_autoload_restrict = IS_ENABLED(CONFIG_MODULE_RESTRICT_AUTOLOAD);
+core_param(modrestrict, module_autoload_restrict, bool, 0);
+
 static const struct ctl_table module_sysctl_table[] = {
 	{
 		.procname	= "modprobe",
@@ -148,6 +152,13 @@ static const struct ctl_table module_sysctl_table[] = {
 		.extra1		= SYSCTL_ONE,
 		.extra2		= SYSCTL_ONE,
 	},
+	{
+		.procname	= "modrestrict",
+		.data		= &module_autoload_restrict,
+		.maxlen		= sizeof(bool),
+		.mode		= 0644,
+		.proc_handler   = proc_dobool,
+	},
 };
 
 static int __init init_module_sysctl(void)

-- 
2.54.0


^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/2] module: add CONFIG_MODULE_RESTRICT_AUTOLOAD
  2026-05-15 17:20 ` [PATCH 1/2] module: add CONFIG_MODULE_RESTRICT_AUTOLOAD Michal Gorlas
@ 2026-05-16  3:03   ` Randy Dunlap
  2026-06-05 18:25   ` Sami Tolvanen
  1 sibling, 0 replies; 7+ messages in thread
From: Randy Dunlap @ 2026-05-16  3:03 UTC (permalink / raw)
  To: Michal Gorlas, Jonathan Corbet, Shuah Khan, Luis Chamberlain,
	Petr Pavlu, Daniel Gomez, Sami Tolvanen, Aaron Tomlin
  Cc: linux-doc, linux-kernel, linux-modules



On 5/15/26 10:20 AM, Michal Gorlas wrote:
> diff --git a/kernel/module/Kconfig b/kernel/module/Kconfig
> index 43b1bb01fd27..c9e01bb848c0 100644
> --- a/kernel/module/Kconfig
> +++ b/kernel/module/Kconfig
> @@ -337,6 +337,21 @@ config MODULE_SIG_HASH
>  
>  endif # MODULE_SIG || IMA_APPRAISE_MODSIG
>  
> +config MODULE_RESTRICT_AUTOLOAD
> +	bool "Restrict module auto-loading to privileged users"
> +	default n
> +	help
> +	  Restrict module auto-loading in response to use of some feature
> +	  implemented by an unloaded module to CAP_SYS_ADMIN. Enabling this
> +	  option helps reducing the attack surface where unprivileged users

	         helps reduce
or
	         helps to reduce

> +	  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.

-- 
~Randy


^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 1/2] module: add CONFIG_MODULE_RESTRICT_AUTOLOAD
  2026-05-15 17:20 ` [PATCH 1/2] module: add CONFIG_MODULE_RESTRICT_AUTOLOAD Michal Gorlas
  2026-05-16  3:03   ` Randy Dunlap
@ 2026-06-05 18:25   ` Sami Tolvanen
  1 sibling, 0 replies; 7+ messages in thread
From: Sami Tolvanen @ 2026-06-05 18:25 UTC (permalink / raw)
  To: Michal Gorlas
  Cc: Jonathan Corbet, Shuah Khan, Luis Chamberlain, Petr Pavlu,
	Daniel Gomez, Aaron Tomlin, linux-doc, linux-kernel,
	linux-modules

On Fri, May 15, 2026 at 07:20:19PM +0200, Michal Gorlas wrote:
> Add CONFIG_MODULE_RESTRICT_AUTOLOAD and modrestrict parameter
> documentation.
> 
> Signed-off-by: Michal Gorlas <michal.gorlas@9elements.com>
> ---
>  Documentation/admin-guide/kernel-parameters.txt |  5 +++++
>  kernel/module/Kconfig                           | 15 +++++++++++++++
>  2 files changed, 20 insertions(+)
> 
> diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
> index 03a550630644..1013104f0943 100644
> --- a/Documentation/admin-guide/kernel-parameters.txt
> +++ b/Documentation/admin-guide/kernel-parameters.txt
> @@ -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.

>  	<module>.async_probe[=<bool>] [KNL]
>  			If no <bool> value is specified or if the value
>  			specified is not a valid <bool>, enable asynchronous
> diff --git a/kernel/module/Kconfig b/kernel/module/Kconfig
> index 43b1bb01fd27..c9e01bb848c0 100644
> --- a/kernel/module/Kconfig
> +++ b/kernel/module/Kconfig
> @@ -337,6 +337,21 @@ config MODULE_SIG_HASH
>  
>  endif # MODULE_SIG || IMA_APPRAISE_MODSIG
>  
> +config MODULE_RESTRICT_AUTOLOAD
> +	bool "Restrict module auto-loading to privileged users"
> +	default n

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

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 2/2] module: restrict autoload to CAP_SYS_ADMIN if CONFIG_MODULE_RESTRICT_AUTOLOAD
  2026-05-15 17:20 ` [PATCH 2/2] module: restrict autoload to CAP_SYS_ADMIN if CONFIG_MODULE_RESTRICT_AUTOLOAD Michal Gorlas
@ 2026-06-05 18:30   ` Sami Tolvanen
  0 siblings, 0 replies; 7+ messages in thread
From: Sami Tolvanen @ 2026-06-05 18:30 UTC (permalink / raw)
  To: Michal Gorlas
  Cc: Jonathan Corbet, Shuah Khan, Luis Chamberlain, Petr Pavlu,
	Daniel Gomez, Aaron Tomlin, linux-doc, linux-kernel,
	linux-modules

On Fri, May 15, 2026 at 07:20:20PM +0200, Michal Gorlas wrote:
> 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 <michal.gorlas@9elements.com>
> ---
>  kernel/module/internal.h |  1 +
>  kernel/module/kmod.c     |  5 +++++
>  kernel/module/main.c     | 11 +++++++++++
>  3 files changed, 17 insertions(+)
> 
> diff --git a/kernel/module/internal.h b/kernel/module/internal.h
> index 061161cc79d9..496d8703f0c6 100644
> --- a/kernel/module/internal.h
> +++ b/kernel/module/internal.h
> @@ -46,6 +46,7 @@ struct kernel_symbol {
>  
>  extern struct mutex module_mutex;
>  extern struct list_head modules;
> +extern bool module_autoload_restrict;
>  
>  extern const struct module_attribute *const modinfo_attrs[];
>  extern const size_t modinfo_attrs_count;
> diff --git a/kernel/module/kmod.c b/kernel/module/kmod.c
> index a25dccdf7aa7..58b28c23f571 100644
> --- a/kernel/module/kmod.c
> +++ b/kernel/module/kmod.c
> @@ -156,6 +156,11 @@ int __request_module(bool wait, const char *fmt, ...)
>  	if (ret)
>  		return ret;
>  
> +	if (module_autoload_restrict && !capable(CAP_SYS_ADMIN)) {
> +		pr_alert("denied attempt to auto-load module %s\n", module_name);

Is pr_alert appropriate here or can this be a warning? Also, use the _ratelimited
variant like the pre-existing warning in this function.

Sami

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH 0/2] module: restrict module auto-loading to privileged users
  2026-05-15 17:20 [PATCH 0/2] module: restrict module auto-loading to privileged users Michal Gorlas
  2026-05-15 17:20 ` [PATCH 1/2] module: add CONFIG_MODULE_RESTRICT_AUTOLOAD Michal Gorlas
  2026-05-15 17:20 ` [PATCH 2/2] module: restrict autoload to CAP_SYS_ADMIN if CONFIG_MODULE_RESTRICT_AUTOLOAD Michal Gorlas
@ 2026-06-05 18:36 ` Sami Tolvanen
  2 siblings, 0 replies; 7+ messages in thread
From: Sami Tolvanen @ 2026-06-05 18:36 UTC (permalink / raw)
  To: Michal Gorlas, Kees Cook
  Cc: Jonathan Corbet, Shuah Khan, Luis Chamberlain, Petr Pavlu,
	Daniel Gomez, Aaron Tomlin, linux-doc, linux-kernel,
	linux-modules

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

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2026-06-05 18:36 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-05-15 17:20 [PATCH 0/2] module: restrict module auto-loading to privileged users Michal Gorlas
2026-05-15 17:20 ` [PATCH 1/2] module: add CONFIG_MODULE_RESTRICT_AUTOLOAD Michal Gorlas
2026-05-16  3:03   ` Randy Dunlap
2026-06-05 18:25   ` Sami Tolvanen
2026-05-15 17:20 ` [PATCH 2/2] module: restrict autoload to CAP_SYS_ADMIN if CONFIG_MODULE_RESTRICT_AUTOLOAD Michal Gorlas
2026-06-05 18:30   ` Sami Tolvanen
2026-06-05 18:36 ` [PATCH 0/2] module: restrict module auto-loading to privileged users Sami Tolvanen

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox