diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2013-07-23 18:37:00 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2013-07-31 22:01:48 +0100 |
commit | f6f91b0d9fd971c630cef908dde8fe8795aefbf8 (patch) | |
tree | 54032cefa513a3ae63971998caa90eea4736180c /arch/arm/kernel/traps.c | |
parent | e39e3f3ebfef03450cf7bfa7a974a8c61f7980c8 (diff) | |
download | linux-f6f91b0d9fd971c630cef908dde8fe8795aefbf8.tar.gz linux-f6f91b0d9fd971c630cef908dde8fe8795aefbf8.tar.bz2 linux-f6f91b0d9fd971c630cef908dde8fe8795aefbf8.zip |
ARM: allow kuser helpers to be removed from the vector page
Provide a kernel configuration option to allow the kernel user helpers
to be removed from the vector page, thereby preventing their use with
ROP (return orientated programming) attacks. This option is only
visible for CPU architectures which natively support all the operations
which kernel user helpers would normally provide, and must be enabled
with caution.
Cc: <stable@vger.kernel.org>
Acked-by: Nicolas Pitre <nico@linaro.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel/traps.c')
-rw-r--r-- | arch/arm/kernel/traps.c | 23 |
1 files changed, 14 insertions, 9 deletions
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c index 2c8c7fa78b8c..e3ca35ccd38e 100644 --- a/arch/arm/kernel/traps.c +++ b/arch/arm/kernel/traps.c @@ -800,15 +800,26 @@ void __init trap_init(void) return; } -static void __init kuser_get_tls_init(unsigned long vectors) +#ifdef CONFIG_KUSER_HELPERS +static void __init kuser_init(void *vectors) { + extern char __kuser_helper_start[], __kuser_helper_end[]; + int kuser_sz = __kuser_helper_end - __kuser_helper_start; + + memcpy(vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz); + /* * vectors + 0xfe0 = __kuser_get_tls * vectors + 0xfe8 = hardware TLS instruction at 0xffff0fe8 */ if (tls_emu || has_tls_reg) - memcpy((void *)vectors + 0xfe0, (void *)vectors + 0xfe8, 4); + memcpy(vectors + 0xfe0, vectors + 0xfe8, 4); +} +#else +static void __init kuser_init(void *vectors) +{ } +#endif void __init early_trap_init(void *vectors_base) { @@ -816,8 +827,6 @@ void __init early_trap_init(void *vectors_base) unsigned long vectors = (unsigned long)vectors_base; extern char __stubs_start[], __stubs_end[]; extern char __vectors_start[], __vectors_end[]; - extern char __kuser_helper_start[], __kuser_helper_end[]; - int kuser_sz = __kuser_helper_end - __kuser_helper_start; unsigned i; vectors_page = vectors_base; @@ -838,12 +847,8 @@ void __init early_trap_init(void *vectors_base) */ memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start); memcpy((void *)vectors + 0x1000, __stubs_start, __stubs_end - __stubs_start); - memcpy((void *)vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz); - /* - * Do processor specific fixups for the kuser helpers - */ - kuser_get_tls_init(vectors); + kuser_init(vectors_base); /* * Copy signal return handlers into the vector page, and |