Hi Dave,
On Fri, Aug 27, 2010 at 08:18:10PM -0400, Dave Jones wrote:
On Fri, Aug 27, 2010 at 04:56:31PM -0700, Kees Cook wrote:
> The NX-emulation should only exist for the 32 bit case, and should not be
> visible under any other situation. This removes the exec-shield parameter
> when not running on 32-bit x86, standardizes the x86_report_nx strings,
> and sets a min/max proc handler for the exec_shield parameter.
I think we should just kill the sysctl and the boot parameter completely,
and make it unconditional.
If we want a switch to disable it, we can overload disable_nx
How does this look? I haven't done a build test yet...
diff --git a/arch/x86/kernel/cpu/common.c b/arch/x86/kernel/cpu/common.c
index aedc466..39e0381 100644
--- a/arch/x86/kernel/cpu/common.c
+++ b/arch/x86/kernel/cpu/common.c
@@ -828,7 +828,7 @@ static void __cpuinit identify_cpu(struct cpuinfo_x86 *c)
* If we have either disabled exec-shield on the boot command line,
* or we have NX, then we don't need to do this.
*/
- if (exec_shield != 0) {
+ if (!disable_nx) {
#ifdef CONFIG_X86_PAE
if (!test_cpu_cap(c, X86_FEATURE_NX))
#endif
diff --git a/arch/x86/mm/setup_nx.c b/arch/x86/mm/setup_nx.c
index e0d9cce..6096e70 100644
--- a/arch/x86/mm/setup_nx.c
+++ b/arch/x86/mm/setup_nx.c
@@ -6,7 +6,7 @@
#include <asm/pgtable.h>
#include <asm/proto.h>
-static int disable_nx __cpuinitdata;
+int disable_nx __cpuinitdata;
/*
* noexec = on|off
@@ -24,7 +24,6 @@ static int __init noexec_setup(char *str)
disable_nx = 0;
} else if (!strncmp(str, "off", 3)) {
disable_nx = 1;
- exec_shield = 0;
}
x86_configure_nx();
return 0;
@@ -42,12 +41,18 @@ void __cpuinit x86_configure_nx(void)
void __init x86_report_nx(void)
{
if (!cpu_has_nx) {
- if (exec_shield)
- printk(KERN_INFO "Using x86 segment limits to approximate NX
protection\n");
+#ifdef CONFIG_X86_32
+ if (disable_nx)
+ printk(KERN_INFO "NX (Execute Disable) protection: "
+ "approximation disabled by kernel command "
+ "line option\n");
else
-
+ printk(KERN_INFO "NX (Execute Disable) protection: "
+ "approximated by x86 segment limits\n");
+#else
printk(KERN_NOTICE "Notice: NX (Execute Disable) protection "
"missing in CPU or disabled in BIOS!\n");
+#endif
} else {
#if defined(CONFIG_X86_64) || defined(CONFIG_X86_PAE)
if (disable_nx) {
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 65e871f..0f464bb 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -722,7 +722,7 @@ static int load_elf_binary(struct linux_binprm *bprm, struct pt_regs
*regs)
* Turn off the CS limit completely if exec-shield disabled or
* NX active:
*/
- if (!exec_shield || executable_stack != EXSTACK_DISABLE_X || (__supported_pte_mask &
_PAGE_NX))
+ if (disable_nx || executable_stack != EXSTACK_DISABLE_X || (__supported_pte_mask &
_PAGE_NX))
arch_add_exec_range(current->mm, -1);
#endif
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 2102309..5ae0dce 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -101,7 +101,9 @@ struct bio_list;
struct fs_struct;
struct perf_event_context;
-extern int exec_shield;
+#ifdef CONFIG_X86_32
+extern int disable_nx;
+#endif
extern int print_fatal_signals;
/*
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index c7f0d4a..62a5a54 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -104,16 +104,6 @@ extern int sysctl_nr_open_min, sysctl_nr_open_max;
extern int sysctl_nr_trim_pages;
#endif
-int exec_shield = 1;
-
-static int __init setup_exec_shield(char *str)
-{
- get_option(&str, &exec_shield);
-
- return 1;
-}
-__setup("exec-shield=", setup_exec_shield);
-
#ifdef CONFIG_BLOCK
extern int blk_iopoll_enabled;
#endif
@@ -441,15 +431,6 @@ static struct ctl_table kern_table[] = {
.mode = 0644,
.proc_handler = proc_dointvec,
},
-#ifdef CONFIG_X86_32
- {
- .procname = "exec-shield",
- .data = &exec_shield,
- .maxlen = sizeof(int),
- .mode = 0644,
- .proc_handler = &proc_dointvec,
- },
-#endif
#ifdef CONFIG_PROC_SYSCTL
{
--
Kees Cook
Ubuntu Security Team