Skip to content

Commit df807e0

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 0135feb commit df807e0

File tree

5 files changed

+54
-0
lines changed

5 files changed

+54
-0
lines changed

Documentation/admin-guide/sysctl/kernel.rst

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ show up in /proc/sys/kernel:
4949
- kexec_load_disabled
5050
- kptr_restrict
5151
- l2cr [ PPC only ]
52+
- modharden
5253
- modprobe ==> Documentation/debugging-modules.txt
5354
- modules_disabled
5455
- msg_next_id [ sysv ipc ]
@@ -446,6 +447,20 @@ This flag controls the L2 cache of G3 processor boards. If
446447
0, the cache is disabled. Enabled if nonzero.
447448

448449

450+
modharden:
451+
=================
452+
453+
This toggle indicates whether unprivileged users are allowed to
454+
auto-load kernel modules.
455+
456+
When modharden is set to (0) there are no restrictions. When
457+
modharden is set to (1), only users with CAP_SYS_MODULE are
458+
permitted to load kernel modules
459+
460+
The kernel config option CONFIG_SECURITY_MODHARDEN sets the
461+
default value of modharden.
462+
463+
449464
modules_disabled:
450465
=================
451466

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
@@ -736,6 +736,15 @@ static struct ctl_table kern_table[] = {
736736
.extra1 = SYSCTL_ONE,
737737
.extra2 = SYSCTL_ONE,
738738
},
739+
{
740+
.procname = "modharden",
741+
.data = &modharden,
742+
.maxlen = sizeof(int),
743+
.mode = 0644,
744+
.proc_handler = proc_dointvec_minmax,
745+
.extra1 = SYSCTL_ZERO,
746+
.extra2 = SYSCTL_ONE,
747+
},
739748
#endif
740749
#ifdef CONFIG_UEVENT_HELPER
741750
{

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)