aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2013-07-23 13:37:00 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2013-08-11 21:35:20 -0400
commit7c5db81779e0ab75fc2d71397911c546046f922f (patch)
tree4dfdda9863c6f37a7cb799380454b92b92d2cb9d /arch
parent6904e468bb92a726098a2dfcf792463e11053582 (diff)
ARM: allow kuser helpers to be removed from the vector page
commit f6f91b0d9fd971c630cef908dde8fe8795aefbf8 upstream. 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. Acked-by: Nicolas Pitre <nico@linaro.org> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'arch')
-rw-r--r--arch/arm/kernel/entry-armv.S3
-rw-r--r--arch/arm/kernel/traps.c23
-rw-r--r--arch/arm/mm/Kconfig34
3 files changed, 51 insertions, 9 deletions
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 4d938421bb9a..d43c7e54ec6c 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -752,6 +752,7 @@ ENDPROC(__switch_to)
752 .endr 752 .endr
753 .endm 753 .endm
754 754
755#ifdef CONFIG_KUSER_HELPERS
755 .align 5 756 .align 5
756 .globl __kuser_helper_start 757 .globl __kuser_helper_start
757__kuser_helper_start: 758__kuser_helper_start:
@@ -938,6 +939,8 @@ __kuser_helper_version: @ 0xffff0ffc
938 .globl __kuser_helper_end 939 .globl __kuser_helper_end
939__kuser_helper_end: 940__kuser_helper_end:
940 941
942#endif
943
941 THUMB( .thumb ) 944 THUMB( .thumb )
942 945
943/* 946/*
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index a58f64e4c714..7751c26f3f0f 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -800,23 +800,32 @@ 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{
815 unsigned long vectors = (unsigned long)vectors_base; 826 unsigned long vectors = (unsigned long)vectors_base;
816 extern char __stubs_start[], __stubs_end[]; 827 extern char __stubs_start[], __stubs_end[];
817 extern char __vectors_start[], __vectors_end[]; 828 extern char __vectors_start[], __vectors_end[];
818 extern char __kuser_helper_start[], __kuser_helper_end[];
819 int kuser_sz = __kuser_helper_end - __kuser_helper_start;
820 unsigned i; 829 unsigned i;
821 830
822 vectors_page = vectors_base; 831 vectors_page = vectors_base;
@@ -837,12 +846,8 @@ void __init early_trap_init(void *vectors_base)
837 */ 846 */
838 memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start); 847 memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start);
839 memcpy((void *)vectors + 0x1000, __stubs_start, __stubs_end - __stubs_start); 848 memcpy((void *)vectors + 0x1000, __stubs_start, __stubs_end - __stubs_start);
840 memcpy((void *)vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz);
841 849
842 /* 850 kuser_init(vectors_base);
843 * Do processor specific fixups for the kuser helpers
844 */
845 kuser_get_tls_init(vectors);
846 851
847 /* 852 /*
848 * Copy signal return handlers into the vector page, and 853 * Copy signal return handlers into the vector page, and
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index 35955b54944c..2950082a531c 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -411,24 +411,28 @@ config CPU_32v3
411 select CPU_USE_DOMAINS if MMU 411 select CPU_USE_DOMAINS if MMU
412 select NEEDS_SYSCALL_FOR_CMPXCHG if SMP 412 select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
413 select TLS_REG_EMUL if SMP || !MMU 413 select TLS_REG_EMUL if SMP || !MMU
414 select NEED_KUSER_HELPERS
414 415
415config CPU_32v4 416config CPU_32v4
416 bool 417 bool
417 select CPU_USE_DOMAINS if MMU 418 select CPU_USE_DOMAINS if MMU
418 select NEEDS_SYSCALL_FOR_CMPXCHG if SMP 419 select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
419 select TLS_REG_EMUL if SMP || !MMU 420 select TLS_REG_EMUL if SMP || !MMU
421 select NEED_KUSER_HELPERS
420 422
421config CPU_32v4T 423config CPU_32v4T
422 bool 424 bool
423 select CPU_USE_DOMAINS if MMU 425 select CPU_USE_DOMAINS if MMU
424 select NEEDS_SYSCALL_FOR_CMPXCHG if SMP 426 select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
425 select TLS_REG_EMUL if SMP || !MMU 427 select TLS_REG_EMUL if SMP || !MMU
428 select NEED_KUSER_HELPERS
426 429
427config CPU_32v5 430config CPU_32v5
428 bool 431 bool
429 select CPU_USE_DOMAINS if MMU 432 select CPU_USE_DOMAINS if MMU
430 select NEEDS_SYSCALL_FOR_CMPXCHG if SMP 433 select NEEDS_SYSCALL_FOR_CMPXCHG if SMP
431 select TLS_REG_EMUL if SMP || !MMU 434 select TLS_REG_EMUL if SMP || !MMU
435 select NEED_KUSER_HELPERS
432 436
433config CPU_32v6 437config CPU_32v6
434 bool 438 bool
@@ -756,6 +760,7 @@ config CPU_BPREDICT_DISABLE
756 760
757config TLS_REG_EMUL 761config TLS_REG_EMUL
758 bool 762 bool
763 select NEED_KUSER_HELPERS
759 help 764 help
760 An SMP system using a pre-ARMv6 processor (there are apparently 765 An SMP system using a pre-ARMv6 processor (there are apparently
761 a few prototypes like that in existence) and therefore access to 766 a few prototypes like that in existence) and therefore access to
@@ -763,11 +768,40 @@ config TLS_REG_EMUL
763 768
764config NEEDS_SYSCALL_FOR_CMPXCHG 769config NEEDS_SYSCALL_FOR_CMPXCHG
765 bool 770 bool
771 select NEED_KUSER_HELPERS
766 help 772 help
767 SMP on a pre-ARMv6 processor? Well OK then. 773 SMP on a pre-ARMv6 processor? Well OK then.
768 Forget about fast user space cmpxchg support. 774 Forget about fast user space cmpxchg support.
769 It is just not possible. 775 It is just not possible.
770 776
777config NEED_KUSER_HELPERS
778 bool
779
780config KUSER_HELPERS
781 bool "Enable kuser helpers in vector page" if !NEED_KUSER_HELPERS
782 default y
783 help
784 Warning: disabling this option may break user programs.
785
786 Provide kuser helpers in the vector page. The kernel provides
787 helper code to userspace in read only form at a fixed location
788 in the high vector page to allow userspace to be independent of
789 the CPU type fitted to the system. This permits binaries to be
790 run on ARMv4 through to ARMv7 without modification.
791
792 However, the fixed address nature of these helpers can be used
793 by ROP (return orientated programming) authors when creating
794 exploits.
795
796 If all of the binaries and libraries which run on your platform
797 are built specifically for your platform, and make no use of
798 these helpers, then you can turn this option off. However,
799 when such an binary or library is run, it will receive a SIGILL
800 signal, which will terminate the program.
801
802 Say N here only if you are absolutely certain that you do not
803 need these helpers; otherwise, the safe option is to say Y.
804
771config DMA_CACHE_RWFO 805config DMA_CACHE_RWFO
772 bool "Enable read/write for ownership DMA cache maintenance" 806 bool "Enable read/write for ownership DMA cache maintenance"
773 depends on CPU_V6K && SMP 807 depends on CPU_V6K && SMP