aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/traps.c
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2013-07-23 13:37:00 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2013-07-31 17:01:48 -0400
commitf6f91b0d9fd971c630cef908dde8fe8795aefbf8 (patch)
tree54032cefa513a3ae63971998caa90eea4736180c /arch/arm/kernel/traps.c
parente39e3f3ebfef03450cf7bfa7a974a8c61f7980c8 (diff)
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.c23
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)
800 return; 800 return;
801} 801}
802 802
803static void __init kuser_get_tls_init(unsigned long vectors) 803#ifdef CONFIG_KUSER_HELPERS
804static void __init kuser_init(void *vectors)
804{ 805{
806 extern char __kuser_helper_start[], __kuser_helper_end[];
807 int kuser_sz = __kuser_helper_end - __kuser_helper_start;
808
809 memcpy(vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz);
810
805 /* 811 /*
806 * vectors + 0xfe0 = __kuser_get_tls 812 * vectors + 0xfe0 = __kuser_get_tls
807 * vectors + 0xfe8 = hardware TLS instruction at 0xffff0fe8 813 * vectors + 0xfe8 = hardware TLS instruction at 0xffff0fe8
808 */ 814 */
809 if (tls_emu || has_tls_reg) 815 if (tls_emu || has_tls_reg)
810 memcpy((void *)vectors + 0xfe0, (void *)vectors + 0xfe8, 4); 816 memcpy(vectors + 0xfe0, vectors + 0xfe8, 4);
817}
818#else
819static void __init kuser_init(void *vectors)
820{
811} 821}
822#endif
812 823
813void __init early_trap_init(void *vectors_base) 824void __init early_trap_init(void *vectors_base)
814{ 825{
@@ -816,8 +827,6 @@ void __init early_trap_init(void *vectors_base)
816 unsigned long vectors = (unsigned long)vectors_base; 827 unsigned long vectors = (unsigned long)vectors_base;
817 extern char __stubs_start[], __stubs_end[]; 828 extern char __stubs_start[], __stubs_end[];
818 extern char __vectors_start[], __vectors_end[]; 829 extern char __vectors_start[], __vectors_end[];
819 extern char __kuser_helper_start[], __kuser_helper_end[];
820 int kuser_sz = __kuser_helper_end - __kuser_helper_start;
821 unsigned i; 830 unsigned i;
822 831
823 vectors_page = vectors_base; 832 vectors_page = vectors_base;
@@ -838,12 +847,8 @@ void __init early_trap_init(void *vectors_base)
838 */ 847 */
839 memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start); 848 memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start);
840 memcpy((void *)vectors + 0x1000, __stubs_start, __stubs_end - __stubs_start); 849 memcpy((void *)vectors + 0x1000, __stubs_start, __stubs_end - __stubs_start);
841 memcpy((void *)vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz);
842 850
843 /* 851 kuser_init(vectors_base);
844 * Do processor specific fixups for the kuser helpers
845 */
846 kuser_get_tls_init(vectors);
847 852
848 /* 853 /*
849 * Copy signal return handlers into the vector page, and 854 * Copy signal return handlers into the vector page, and