diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig
index 71ca1995a088..2c7d447401b5 100644
--- a/arch/arm64/Kconfig
+++ b/arch/arm64/Kconfig
@@ -1333,6 +1333,27 @@ config COMPAT
If you want to execute 32-bit userspace applications, say Y.
+config KUSER_HELPERS
+ bool "Enable kuser helpers page for compatibility with 32 bit applications."
+ depends on COMPAT
+ default y
+ help
+ Enables kuser helpers to be mapped in a special purpose page at a fixed
+ address to maintain independence from the type of CPU present in the SoC.
+ This feature is provided for compatibility reasons in fact allows 32 bit
+ applications compliant with ARMv4 up to ARMv8 to run without any
+ modification.
+
+ Warning: Being always mapped at a fixed address makes it easier to create
+ exploits based on ROP type of attacks.
+
+ As a consequence of this, this feature is made configurable but be aware that
+ it can be turned off if and only if the binaries and the libraries running on
+ a specific platform are designed to do not make use of these helpers, otherwise
+ should be left on.
+
+ See Documentation/arm/kernel_user_helpers.txt for details.
+
config SYSVIPC_COMPAT
def_bool y
depends on COMPAT && SYSVIPC
diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile
index 6bd4f619732a..2fcba6b87829 100644
--- a/arch/arm64/kernel/Makefile
+++ b/arch/arm64/kernel/Makefile
@@ -27,8 +27,9 @@ OBJCOPYFLAGS := --prefix-symbols=__efistub_
$(obj)/%.stub.o: $(obj)/%.o FORCE
$(call if_changed,objcopy)
-arm64-obj-$(CONFIG_COMPAT) += sys32.o kuser32.o signal32.o \
+arm64-obj-$(CONFIG_COMPAT) += sys32.o signal32.o \
sigreturn32.o sys_compat.o
+arm64-obj-$(CONFIG_KUSER_HELPERS) += kuser32.o
arm64-obj-$(CONFIG_FUNCTION_TRACER) += ftrace.o entry-ftrace.o
arm64-obj-$(CONFIG_MODULES) += arm64ksyms.o module.o
arm64-obj-$(CONFIG_ARM64_MODULE_PLTS) += module-plts.o
diff --git a/arch/arm64/kernel/kuser32.S b/arch/arm64/kernel/kuser32.S
index f19e2b015097..7d38633bf33f 100644
--- a/arch/arm64/kernel/kuser32.S
+++ b/arch/arm64/kernel/kuser32.S
@@ -5,10 +5,9 @@
* Copyright (C) 2005-2011 Nicolas Pitre <nico@fluxnic.net>
* Copyright (C) 2012-2018 ARM Ltd.
*
- * Each segment is 32-byte aligned and will be moved to the top of the high
- * vector page. New segments (if ever needed) must be added in front of
- * existing ones. This mechanism should be used only for things that are
- * really small and justified, and not be abused freely.
+ * The kuser helpers below are mapped at a fixed address by
+ * aarch32_setup_additional_pages() ad are provided for compatibility
+ * reasons with 32 bit (aarch32) applications that need them.
*
* See Documentation/arm/kernel_user_helpers.txt for formal definitions.
*/
diff --git a/arch/arm64/kernel/vdso.c b/arch/arm64/kernel/vdso.c
index cee7205eefc5..8903087cca4c 100644
--- a/arch/arm64/kernel/vdso.c
+++ b/arch/arm64/kernel/vdso.c
@@ -74,6 +74,7 @@ static const struct vm_special_mapping aarch32_vdso_spec[2] = {
},
};
+#ifdef CONFIG_KUSER_HELPERS
static int aarch32_alloc_kuser_vdso_page(void)
{
extern char __kuser_helper_start[], __kuser_helper_end[];@@ -95,6 +96,12 @@ static int aarch32_alloc_kuser_vdso_page(void)
return 0;
}
+#else
+static int aarch32_alloc_kuser_vdso_page(void)
+{
+ return 0;
+}
+#endif /* CONFIG_KUSER_HELPER */
static int aarch32_alloc_sigreturn_vdso_page(void)
{@@ -126,6 +133,7 @@ static int __init aarch32_alloc_vdso_pages(void)
}
arch_initcall(aarch32_alloc_vdso_pages);
+#ifdef CONFIG_KUSER_HELPERS
static int aarch32_kuser_helpers_setup(struct mm_struct *mm)
{
void *ret;@@ -138,6 +146,13 @@ static int aarch32_kuser_helpers_setup(struct mm_struct *mm)
return PTR_ERR_OR_ZERO(ret);
}
+#else
+static int aarch32_kuser_helpers_setup(struct mm_struct *mm)
+{
+ /* kuser helpers not enabled */
+ return 0;
+}
+#endif /* CONFIG_KUSER_HELPERS */
static int aarch32_sigreturn_setup(struct mm_struct *mm)
{--
2.19.1