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.
Signed-off-by: Kees Cook <kees.cook(a)canonical.com>
---
arch/x86/mm/setup_nx.c | 12 ++++++++++--
include/linux/sched.h | 2 ++
kernel/sysctl.c | 6 +++++-
3 files changed, 17 insertions(+), 3 deletions(-)
diff --git a/arch/x86/mm/setup_nx.c b/arch/x86/mm/setup_nx.c
index e0d9cce..f068676 100644
--- a/arch/x86/mm/setup_nx.c
+++ b/arch/x86/mm/setup_nx.c
@@ -24,7 +24,9 @@ static int __init noexec_setup(char *str)
disable_nx = 0;
} else if (!strncmp(str, "off", 3)) {
disable_nx = 1;
+#ifdef CONFIG_X86_32
exec_shield = 0;
+#endif
}
x86_configure_nx();
return 0;
@@ -42,12 +44,18 @@ void __cpuinit x86_configure_nx(void)
void __init x86_report_nx(void)
{
if (!cpu_has_nx) {
+#ifdef CONFIG_X86_32
if (exec_shield)
- printk(KERN_INFO "Using x86 segment limits to approximate NX protection\n");
+ printk(KERN_INFO "NX (Execute Disable) protection: "
+ "approximated by x86 segment limits\n");
else
-
+ printk(KERN_INFO "NX (Execute Disable) protection: "
+ "approximation disabled by kernel command "
+ "line option\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/include/linux/sched.h b/include/linux/sched.h
index 2102309..5606aa7 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;
+#ifdef CONFIG_X86_32
extern int exec_shield;
+#endif
extern int print_fatal_signals;
/*
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index c7f0d4a..68f020f 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -104,6 +104,7 @@ extern int sysctl_nr_open_min, sysctl_nr_open_max;
extern int sysctl_nr_trim_pages;
#endif
+#ifdef CONFIG_X86_32
int exec_shield = 1;
static int __init setup_exec_shield(char *str)
@@ -113,6 +114,7 @@ static int __init setup_exec_shield(char *str)
return 1;
}
__setup("exec-shield=", setup_exec_shield);
+#endif
#ifdef CONFIG_BLOCK
extern int blk_iopoll_enabled;
@@ -447,7 +449,9 @@ static struct ctl_table kern_table[] = {
.data = &exec_shield,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = &proc_dointvec,
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = &zero,
+ .extra2 = &one,
},
#endif
--
1.7.1
--
Kees Cook
Ubuntu Security Team