[PATCH v5] MIPS: Add noexec=on|off kernel parameter
From: Aleksandar Markovic
Date: Tue Jan 09 2018 - 06:57:51 EST
From: Miodrag Dinic <miodrag.dinic@xxxxxxxx>
Add a new kernel parameter to override the default behavior related to
the decision whether to indicate stack as non-executable or executable
(regardless of PT_GNU_STACK entry or CPU RIXI support) in function
mips_elf_read_implies_exec().
Allowed values:
noexec=on: force indicating non-exec stack & heap
noexec=off: force indicating executable stack & heap
If this parameter is omitted, kernel behavior remains the same as it
was before this patch is applied.
This functionality is convenient during debugging and is especially
useful for Android development where indication of non-executable
stack is required.
NOTE: Using noexec=on on a system without CPU XI support is not
recommended since there is no actual HW support that provide
non-executable stack and heap. Use only for debugging purposes and
not in a production environment.
Signed-off-by: Miodrag Dinic <miodrag.dinic@xxxxxxxx>
Signed-off-by: Aleksandar Markovic <aleksandar.markovic@xxxxxxxx>
---
In the last version, code comments, documentation, and commit message
are modified to better explain the purpose and nature of this option.
A precautionary note is added as well.
---
Documentation/admin-guide/kernel-parameters.txt | 19 ++++++++++
arch/mips/kernel/elf.c | 48 +++++++++++++++++++++++++
2 files changed, 67 insertions(+)
diff --git a/Documentation/admin-guide/kernel-parameters.txt b/Documentation/admin-guide/kernel-parameters.txt
index af7104a..64c562a 100644
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -2600,6 +2600,25 @@
noexec=on: enable non-executable mappings (default)
noexec=off: disable non-executable mappings
+ noexec [MIPS]
+ Force indicating stack and heap as non-executable or
+ executable regardless of PT_GNU_STACK entry or CPU XI
+ (execute inhibit) support. Valid valuess are: on, off.
+ noexec=on: force indicating non-executable
+ stack and heap
+ noexec=off: force indicating executable
+ stack and heap
+ If this parameter is omitted, stack and heap will be
+ indicated non-executable or executable as they are
+ actually set up, which depends on PT_GNU_STACK entry
+ and possibly other factors (for instance, CPU XI
+ support).
+ NOTE: Using noexec=on on a system without CPU XI
+ support is not recommended since there is no actual
+ HW support that provide non-executable stack/heap.
+ Use only for debugging purposes and not in a
+ production environment.
+
nosmap [X86]
Disable SMAP (Supervisor Mode Access Prevention)
even if it is supported by processor.
diff --git a/arch/mips/kernel/elf.c b/arch/mips/kernel/elf.c
index 731325a..9bb40cc 100644
--- a/arch/mips/kernel/elf.c
+++ b/arch/mips/kernel/elf.c
@@ -326,8 +326,56 @@ void mips_set_personality_nan(struct arch_elf_state *state)
}
}
+static int noexec = EXSTACK_DEFAULT;
+
+/*
+ * kernel parameter: noexec=on|off
+ *
+ * Force indicating stack and heap as non-executable or
+ * executable regardless of PT_GNU_STACK entry or CPU XI
+ * (execute inhibit) support. Valid valuess are: on, off.
+ *
+ * noexec=on: force indicating non-executable
+ * stack and heap
+ * noexec=off: force indicating executable
+ * stack and heap
+ *
+ * If this parameter is omitted, stack and heap will be
+ * indicated non-executable or executable as they are
+ * actually set up, which depends on PT_GNU_STACK entry
+ * and possibly other factors (for instance, CPU XI
+ * support).
+ *
+ * NOTE: Using noexec=on on a system without CPU XI
+ * support is not recommended since there is no actual
+ * HW support that provide non-executable stack/heap.
+ * Use only for debugging purposes and not in a
+ * production environment.
+ */
+static int __init noexec_setup(char *str)
+{
+ if (!strcmp(str, "on"))
+ noexec = EXSTACK_DISABLE_X;
+ else if (!strcmp(str, "off"))
+ noexec = EXSTACK_ENABLE_X;
+ else
+ pr_err("Malformed noexec format! noexec=on|off\n");
+
+ return 1;
+}
+__setup("noexec=", noexec_setup);
+
int mips_elf_read_implies_exec(void *elf_ex, int exstack)
{
+ switch (noexec) {
+ case EXSTACK_DISABLE_X:
+ return 0;
+ case EXSTACK_ENABLE_X:
+ return 1;
+ default:
+ break;
+ }
+
if (exstack != EXSTACK_DISABLE_X) {
/* The binary doesn't request a non-executable stack */
return 1;
--
2.7.4