Skip to content

Commit 1e397eb

Browse files
committed
Harden module auto-loading
This is modified from Brad Spengler/PaX Team's code in the last public patch of grsecurity/PaX based on my understanding of the code. Changes or omissions from the original code are mine and don't reflect the original grsecurity/PaX code. 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.
1 parent 2167374 commit 1e397eb

File tree

5 files changed

+55
-2
lines changed

5 files changed

+55
-2
lines changed

Documentation/admin-guide/sysctl/kernel.rst

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -405,8 +405,22 @@ loaded; it won't have any effect if the module is being loaded
405405
explicitly using ``modprobe`` from userspace.
406406

407407

408-
modules_disabled
409-
================
408+
modharden:
409+
=================
410+
411+
This toggle indicates whether unprivileged users are allowed to
412+
auto-load kernel modules.
413+
414+
When modharden is set to (0) there are no restrictions. When
415+
modharden is set to (1), only users with CAP_SYS_MODULE are
416+
permitted to load kernel modules
417+
418+
The kernel config option CONFIG_SECURITY_MODHARDEN sets the
419+
default value of modharden.
420+
421+
422+
modules_disabled:
423+
=================
410424

411425
A toggle value indicating if modules are allowed to be loaded
412426
in an otherwise modular kernel. This toggle defaults to off

include/linux/kmod.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ extern char modprobe_path[]; /* for sysctl */
2222
* usually useless though. */
2323
extern __printf(2, 3)
2424
int __request_module(bool wait, const char *name, ...);
25+
extern int modharden;
2526
#define request_module(mod...) __request_module(true, mod)
2627
#define request_module_nowait(mod...) __request_module(false, mod)
2728
#define try_then_request_module(x, mod...) \

kernel/kmod.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ static int call_modprobe(char *module_name, int wait)
106106
return -ENOMEM;
107107
}
108108

109+
int modharden = IS_ENABLED(CONFIG_SECURITY_MODHARDEN);
110+
109111
/**
110112
* __request_module - try to load a kernel module
111113
* @wait: wait (or not) for the operation to complete
@@ -149,6 +151,11 @@ int __request_module(bool wait, const char *fmt, ...)
149151
if (ret)
150152
return ret;
151153

154+
if (modharden && !capable(CAP_SYS_MODULE)) {
155+
printk(KERN_ALERT "denied attempt to auto-load module %s\n", module_name);
156+
return -EPERM;
157+
}
158+
152159
if (atomic_dec_if_positive(&kmod_concurrent_max) < 0) {
153160
pr_warn_ratelimited("request_module: kmod_concurrent_max (%u) close to 0 (max_modprobes: %u), for module %s, throttling...",
154161
atomic_read(&kmod_concurrent_max),

kernel/sysctl.c

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,15 @@ static struct ctl_table kern_table[] = {
724724
.extra1 = SYSCTL_ONE,
725725
.extra2 = SYSCTL_ONE,
726726
},
727+
{
728+
.procname = "modharden",
729+
.data = &modharden,
730+
.maxlen = sizeof(int),
731+
.mode = 0644,
732+
.proc_handler = proc_dointvec_minmax,
733+
.extra1 = SYSCTL_ZERO,
734+
.extra2 = SYSCTL_ONE,
735+
},
727736
#endif
728737
#ifdef CONFIG_UEVENT_HELPER
729738
{

security/Kconfig

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,28 @@ config SECURITY_TIOCSTI_RESTRICT
4242

4343
If you are unsure how to answer this question, answer N.
4444

45+
config SECURITY_MODHARDEN
46+
bool "Harden module auto-loading"
47+
default y
48+
depends on MODULES
49+
help
50+
If you say Y here, module auto-loading in response to use of some
51+
feature implemented by an unloaded module will be restricted to
52+
CAP_SYS_MODULE. Enabling this option helps defend against attacks
53+
by unprivileged users who abuse the auto-loading behavior to
54+
cause a vulnerable module to load that is then exploited.
55+
56+
If this option prevents a legitimate use of auto-loading for a
57+
non-root user, the administrator can execute modprobe manually
58+
with the exact name of the module mentioned in the alert log.
59+
Alternatively, the administrator can add the module to the list
60+
of modules loaded at boot by modifying init scripts.
61+
62+
Modification of init scripts will most likely be needed on
63+
Ubuntu servers with encrypted home directory support enabled,
64+
as the first non-root user logging in will cause the ecb(aes),
65+
ecb(aes)-all, cbc(aes), and cbc(aes)-all modules to be loaded.
66+
4567
config SECURITY
4668
bool "Enable different security models"
4769
depends on SYSFS

0 commit comments

Comments
 (0)