aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/sysctl/kernel.txt11
-rw-r--r--kernel/module.c7
-rw-r--r--kernel/sysctl.c12
3 files changed, 28 insertions, 2 deletions
diff --git a/Documentation/sysctl/kernel.txt b/Documentation/sysctl/kernel.txt
index a4ccdd1981cf..02b134956273 100644
--- a/Documentation/sysctl/kernel.txt
+++ b/Documentation/sysctl/kernel.txt
@@ -30,6 +30,7 @@ show up in /proc/sys/kernel:
30- kstack_depth_to_print [ X86 only ] 30- kstack_depth_to_print [ X86 only ]
31- l2cr [ PPC only ] 31- l2cr [ PPC only ]
32- modprobe ==> Documentation/debugging-modules.txt 32- modprobe ==> Documentation/debugging-modules.txt
33- modules_disabled
33- msgmax 34- msgmax
34- msgmnb 35- msgmnb
35- msgmni 36- msgmni
@@ -179,6 +180,16 @@ kernel stack.
179 180
180============================================================== 181==============================================================
181 182
183modules_disabled:
184
185A toggle value indicating if modules are allowed to be loaded
186in an otherwise modular kernel. This toggle defaults to off
187(0), but can be set true (1). Once true, modules can be
188neither loaded nor unloaded, and the toggle cannot be set back
189to false.
190
191==============================================================
192
182osrelease, ostype & version: 193osrelease, ostype & version:
183 194
184# cat osrelease 195# cat osrelease
diff --git a/kernel/module.c b/kernel/module.c
index f77ac320d0b5..eeb3f7b1383c 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -778,6 +778,9 @@ static void wait_for_zero_refcount(struct module *mod)
778 mutex_lock(&module_mutex); 778 mutex_lock(&module_mutex);
779} 779}
780 780
781/* Block module loading/unloading? */
782int modules_disabled = 0;
783
781SYSCALL_DEFINE2(delete_module, const char __user *, name_user, 784SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
782 unsigned int, flags) 785 unsigned int, flags)
783{ 786{
@@ -785,7 +788,7 @@ SYSCALL_DEFINE2(delete_module, const char __user *, name_user,
785 char name[MODULE_NAME_LEN]; 788 char name[MODULE_NAME_LEN];
786 int ret, forced = 0; 789 int ret, forced = 0;
787 790
788 if (!capable(CAP_SYS_MODULE)) 791 if (!capable(CAP_SYS_MODULE) || modules_disabled)
789 return -EPERM; 792 return -EPERM;
790 793
791 if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0) 794 if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0)
@@ -2349,7 +2352,7 @@ SYSCALL_DEFINE3(init_module, void __user *, umod,
2349 int ret = 0; 2352 int ret = 0;
2350 2353
2351 /* Must have permission */ 2354 /* Must have permission */
2352 if (!capable(CAP_SYS_MODULE)) 2355 if (!capable(CAP_SYS_MODULE) || modules_disabled)
2353 return -EPERM; 2356 return -EPERM;
2354 2357
2355 /* Only one module load at a time, please */ 2358 /* Only one module load at a time, please */
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index c5ef44ff850f..2fb4246d27de 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -113,6 +113,7 @@ static int ngroups_max = NGROUPS_MAX;
113 113
114#ifdef CONFIG_MODULES 114#ifdef CONFIG_MODULES
115extern char modprobe_path[]; 115extern char modprobe_path[];
116extern int modules_disabled;
116#endif 117#endif
117#ifdef CONFIG_CHR_DEV_SG 118#ifdef CONFIG_CHR_DEV_SG
118extern int sg_big_buff; 119extern int sg_big_buff;
@@ -533,6 +534,17 @@ static struct ctl_table kern_table[] = {
533 .proc_handler = &proc_dostring, 534 .proc_handler = &proc_dostring,
534 .strategy = &sysctl_string, 535 .strategy = &sysctl_string,
535 }, 536 },
537 {
538 .ctl_name = CTL_UNNUMBERED,
539 .procname = "modules_disabled",
540 .data = &modules_disabled,
541 .maxlen = sizeof(int),
542 .mode = 0644,
543 /* only handle a transition from default "0" to "1" */
544 .proc_handler = &proc_dointvec_minmax,
545 .extra1 = &one,
546 .extra2 = &one,
547 },
536#endif 548#endif
537#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET) 549#if defined(CONFIG_HOTPLUG) && defined(CONFIG_NET)
538 { 550 {