diff --git a/Documentation/admin-guide/sysctl/kernel.rst b/Documentation/admin-guide/sysctl/kernel.rst index cff409b35952f..b8d78f5522053 100644 --- a/Documentation/admin-guide/sysctl/kernel.rst +++ b/Documentation/admin-guide/sysctl/kernel.rst @@ -405,8 +405,22 @@ loaded; it won't have any effect if the module is being loaded explicitly using ``modprobe`` from userspace. -modules_disabled -================ +modharden: +================= + +This toggle indicates whether unprivileged users are allowed to +auto-load kernel modules. + +When modharden is set to (0) there are no restrictions. When +modharden is set to (1), only users with CAP_SYS_MODULE are +permitted to load kernel modules + +The kernel config option CONFIG_SECURITY_MODHARDEN sets the +default value of modharden. + + +modules_disabled: +================= A toggle value indicating if modules are allowed to be loaded in an otherwise modular kernel. This toggle defaults to off diff --git a/include/linux/kmod.h b/include/linux/kmod.h index 68f69362d427c..6762f35c29eb9 100644 --- a/include/linux/kmod.h +++ b/include/linux/kmod.h @@ -22,6 +22,7 @@ extern char modprobe_path[]; /* for sysctl */ * usually useless though. */ extern __printf(2, 3) int __request_module(bool wait, const char *name, ...); +extern int modharden; #define request_module(mod...) __request_module(true, mod) #define request_module_nowait(mod...) __request_module(false, mod) #define try_then_request_module(x, mod...) \ diff --git a/kernel/kmod.c b/kernel/kmod.c index bc6addd9152b4..48fbb8fe72b80 100644 --- a/kernel/kmod.c +++ b/kernel/kmod.c @@ -106,6 +106,8 @@ static int call_modprobe(char *module_name, int wait) return -ENOMEM; } +int modharden = IS_ENABLED(CONFIG_SECURITY_MODHARDEN); + /** * __request_module - try to load a kernel module * @wait: wait (or not) for the operation to complete @@ -149,6 +151,11 @@ int __request_module(bool wait, const char *fmt, ...) if (ret) return ret; + if (modharden && !capable(CAP_SYS_MODULE)) { + printk(KERN_ALERT "denied attempt to auto-load module %s\n", module_name); + return -EPERM; + } + if (atomic_dec_if_positive(&kmod_concurrent_max) < 0) { pr_warn_ratelimited("request_module: kmod_concurrent_max (%u) close to 0 (max_modprobes: %u), for module %s, throttling...", atomic_read(&kmod_concurrent_max), diff --git a/kernel/sysctl.c b/kernel/sysctl.c index 87bc1d26c3760..623aae96ff4c8 100644 --- a/kernel/sysctl.c +++ b/kernel/sysctl.c @@ -724,6 +724,15 @@ static struct ctl_table kern_table[] = { .extra1 = SYSCTL_ONE, .extra2 = SYSCTL_ONE, }, + { + .procname = "modharden", + .data = &modharden, + .maxlen = sizeof(int), + .mode = 0644, + .proc_handler = proc_dointvec_minmax, + .extra1 = SYSCTL_ZERO, + .extra2 = SYSCTL_ONE, + }, #endif #ifdef CONFIG_UEVENT_HELPER { diff --git a/security/Kconfig b/security/Kconfig index 127b54aecf87e..ddf60c64f4d06 100644 --- a/security/Kconfig +++ b/security/Kconfig @@ -42,6 +42,28 @@ config SECURITY_TIOCSTI_RESTRICT If you are unsure how to answer this question, answer N. +config SECURITY_MODHARDEN + bool "Harden module auto-loading" + default y + depends on MODULES + help + If you say Y here, module auto-loading in response to use of some + feature implemented by an unloaded module will be restricted to + CAP_SYS_MODULE. Enabling this option helps defend against attacks + by unprivileged users who abuse the auto-loading behavior to + cause a vulnerable module to load that is then exploited. + + If this option prevents a legitimate use of auto-loading for a + non-root user, the administrator can execute modprobe manually + with the exact name of the module mentioned in the alert log. + Alternatively, the administrator can add the module to the list + of modules loaded at boot by modifying init scripts. + + Modification of init scripts will most likely be needed on + Ubuntu servers with encrypted home directory support enabled, + as the first non-root user logging in will cause the ecb(aes), + ecb(aes)-all, cbc(aes), and cbc(aes)-all modules to be loaded. + config SECURITY bool "Enable different security models" depends on SYSFS