Skip to content

Commit

Permalink
modules: sysctl to block module loading
Browse files Browse the repository at this point in the history
Implement a sysctl file that disables module-loading system-wide since
there is no longer a viable way to remove CAP_SYS_MODULE after the system
bounding capability set was removed in 2.6.25.

Value can only be set to "1", and is tested only if standard capability
checks allow CAP_SYS_MODULE.  Given existing /dev/mem protections, this
should allow administrators a one-way method to block module loading
after initial boot-time module loading has finished.

Signed-off-by: Kees Cook <kees.cook@canonical.com>
Acked-by: Serge Hallyn <serue@us.ibm.com>
Signed-off-by: James Morris <jmorris@namei.org>
  • Loading branch information
Kees Cook authored and James Morris committed Apr 3, 2009
1 parent 8a6f83a commit 3d43321
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 2 deletions.
11 changes: 11 additions & 0 deletions Documentation/sysctl/kernel.txt
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ show up in /proc/sys/kernel:
- kstack_depth_to_print [ X86 only ]
- l2cr [ PPC only ]
- modprobe ==> Documentation/debugging-modules.txt
- modules_disabled
- msgmax
- msgmnb
- msgmni
Expand Down Expand Up @@ -179,6 +180,16 @@ kernel stack.

==============================================================

modules_disabled:

A toggle value indicating if modules are allowed to be loaded
in an otherwise modular kernel. This toggle defaults to off
(0), but can be set true (1). Once true, modules can be
neither loaded nor unloaded, and the toggle cannot be set back
to false.

==============================================================

osrelease, ostype & version:

# cat osrelease
Expand Down
7 changes: 5 additions & 2 deletions kernel/module.c
Original file line number Diff line number Diff line change
Expand Up @@ -778,14 +778,17 @@ static void wait_for_zero_refcount(struct module *mod)
mutex_lock(&module_mutex);
}

/* Block module loading/unloading? */
int modules_disabled = 0;

SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
unsigned int, flags)
{
struct module *mod;
char name[MODULE_NAME_LEN];
int ret, forced = 0;

if (!capable(CAP_SYS_MODULE))
if (!capable(CAP_SYS_MODULE) || modules_disabled)
return -EPERM;

if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0)
Expand Down Expand Up @@ -2349,7 +2352,7 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
int ret = 0;

/* Must have permission */
if (!capable(CAP_SYS_MODULE))
if (!capable(CAP_SYS_MODULE) || modules_disabled)
return -EPERM;

/* Only one module load at a time, please */
Expand Down
12 changes: 12 additions & 0 deletions kernel/sysctl.c
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ static int ngroups_max = NGROUPS_MAX;

#ifdef CONFIG_MODULES
extern char modprobe_path[];
extern int modules_disabled;
#endif
#ifdef CONFIG_CHR_DEV_SG
extern int sg_big_buff;
Expand Down Expand Up @@ -533,6 +534,17 @@ static struct ctl_table kern_table[] = {
.proc_handler = &proc_dostring,
.strategy = &sysctl_string,
},
{
.ctl_name = CTL_UNNUMBERED,
.procname = "modules_disabled",
.data = &modules_disabled,
.maxlen = sizeof(int),
.mode = 0644,
/* only handle a transition from default "0" to "1" */
.proc_handler = &proc_dointvec_minmax,
.extra1 = &one,
.extra2 = &one,
},
#endif
#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
{
Expand Down

0 comments on commit 3d43321

Please sign in to comment.