aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorRussell King <rmk+kernel@arm.linux.org.uk>2013-07-04 06:40:32 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2013-07-31 16:31:36 -0400
commit19accfd373847ac3d10623c5d20f948846299741 (patch)
tree682dd44ea1710afbb7e61a24185ffa4c9a0fb0da /arch
parent5b43e7a383d69381ffe53423e46dd0fafae07da3 (diff)
ARM: move vector stubs
Move the machine vector stubs into the page above the vector page, which we can prevent from being visible to userspace. Also move the reset stub, and place the swi vector at a location that the 'ldr' can get to it. This hides pointers into the kernel which could give valuable information to attackers, and reduces the number of exploitable instructions at a fixed address. 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')
-rw-r--r--arch/arm/Kconfig3
-rw-r--r--arch/arm/kernel/entry-armv.S50
-rw-r--r--arch/arm/kernel/traps.c4
-rw-r--r--arch/arm/mm/mmu.c10
4 files changed, 37 insertions, 30 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index ba412e02ec0c..123b7924904f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -218,7 +218,8 @@ config VECTORS_BASE
218 default DRAM_BASE if REMAP_VECTORS_TO_RAM 218 default DRAM_BASE if REMAP_VECTORS_TO_RAM
219 default 0x00000000 219 default 0x00000000
220 help 220 help
221 The base address of exception vectors. 221 The base address of exception vectors. This must be two pages
222 in size.
222 223
223config ARM_PATCH_PHYS_VIRT 224config ARM_PATCH_PHYS_VIRT
224 bool "Patch physical to virtual translations at runtime" if EMBEDDED 225 bool "Patch physical to virtual translations at runtime" if EMBEDDED
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 02437345289a..79a41fa978f5 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -944,9 +944,9 @@ __kuser_helper_end:
944/* 944/*
945 * Vector stubs. 945 * Vector stubs.
946 * 946 *
947 * This code is copied to 0xffff0200 so we can use branches in the 947 * This code is copied to 0xffff1000 so we can use branches in the
948 * vectors, rather than ldr's. Note that this code must not 948 * vectors, rather than ldr's. Note that this code must not exceed
949 * exceed 0x300 bytes. 949 * a page size.
950 * 950 *
951 * Common stub entry macro: 951 * Common stub entry macro:
952 * Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC 952 * Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
@@ -995,6 +995,15 @@ ENDPROC(vector_\name)
995 995
996 .globl __stubs_start 996 .globl __stubs_start
997__stubs_start: 997__stubs_start:
998 @ This must be the first word
999 .word vector_swi
1000
1001vector_rst:
1002 ARM( swi SYS_ERROR0 )
1003 THUMB( svc #0 )
1004 THUMB( nop )
1005 b vector_und
1006
998/* 1007/*
999 * Interrupt dispatcher 1008 * Interrupt dispatcher
1000 */ 1009 */
@@ -1089,6 +1098,16 @@ __stubs_start:
1089 .align 5 1098 .align 5
1090 1099
1091/*============================================================================= 1100/*=============================================================================
1101 * Address exception handler
1102 *-----------------------------------------------------------------------------
1103 * These aren't too critical.
1104 * (they're not supposed to happen, and won't happen in 32-bit data mode).
1105 */
1106
1107vector_addrexcptn:
1108 b vector_addrexcptn
1109
1110/*=============================================================================
1092 * Undefined FIQs 1111 * Undefined FIQs
1093 *----------------------------------------------------------------------------- 1112 *-----------------------------------------------------------------------------
1094 * Enter in FIQ mode, spsr = ANY CPSR, lr = ANY PC 1113 * Enter in FIQ mode, spsr = ANY CPSR, lr = ANY PC
@@ -1101,35 +1120,14 @@ __stubs_start:
1101vector_fiq: 1120vector_fiq:
1102 subs pc, lr, #4 1121 subs pc, lr, #4
1103 1122
1104/*=============================================================================
1105 * Address exception handler
1106 *-----------------------------------------------------------------------------
1107 * These aren't too critical.
1108 * (they're not supposed to happen, and won't happen in 32-bit data mode).
1109 */
1110
1111vector_addrexcptn:
1112 b vector_addrexcptn
1113
1114/*
1115 * We group all the following data together to optimise
1116 * for CPUs with separate I & D caches.
1117 */
1118 .align 5
1119
1120.LCvswi:
1121 .word vector_swi
1122
1123 .globl __stubs_end 1123 .globl __stubs_end
1124__stubs_end: 1124__stubs_end:
1125 1125
1126 .equ stubs_offset, __vectors_start + 0x200 - __stubs_start 1126 .equ stubs_offset, __vectors_start + 0x1000 - __stubs_start
1127 1127
1128 .globl __vectors_start 1128 .globl __vectors_start
1129__vectors_start: 1129__vectors_start:
1130 ARM( swi SYS_ERROR0 ) 1130 W(b) vector_rst + stubs_offset
1131 THUMB( svc #0 )
1132 THUMB( nop )
1133 W(b) vector_und + stubs_offset 1131 W(b) vector_und + stubs_offset
1134 W(ldr) pc, .LCvswi + stubs_offset 1132 W(ldr) pc, .LCvswi + stubs_offset
1135 W(b) vector_pabt + stubs_offset 1133 W(b) vector_pabt + stubs_offset
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 9433e8a12b5e..2c8c7fa78b8c 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -837,7 +837,7 @@ void __init early_trap_init(void *vectors_base)
837 * are visible to the instruction stream. 837 * are visible to the instruction stream.
838 */ 838 */
839 memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start); 839 memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start);
840 memcpy((void *)vectors + 0x200, __stubs_start, __stubs_end - __stubs_start); 840 memcpy((void *)vectors + 0x1000, __stubs_start, __stubs_end - __stubs_start);
841 memcpy((void *)vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz); 841 memcpy((void *)vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz);
842 842
843 /* 843 /*
@@ -852,7 +852,7 @@ void __init early_trap_init(void *vectors_base)
852 memcpy((void *)(vectors + KERN_SIGRETURN_CODE - CONFIG_VECTORS_BASE), 852 memcpy((void *)(vectors + KERN_SIGRETURN_CODE - CONFIG_VECTORS_BASE),
853 sigreturn_codes, sizeof(sigreturn_codes)); 853 sigreturn_codes, sizeof(sigreturn_codes));
854 854
855 flush_icache_range(vectors, vectors + PAGE_SIZE); 855 flush_icache_range(vectors, vectors + PAGE_SIZE * 2);
856 modify_domain(DOMAIN_USER, DOMAIN_CLIENT); 856 modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
857#else /* ifndef CONFIG_CPU_V7M */ 857#else /* ifndef CONFIG_CPU_V7M */
858 /* 858 /*
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 4f56617a2392..9ea274d1af69 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -1160,7 +1160,7 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
1160 /* 1160 /*
1161 * Allocate the vector page early. 1161 * Allocate the vector page early.
1162 */ 1162 */
1163 vectors = early_alloc(PAGE_SIZE); 1163 vectors = early_alloc(PAGE_SIZE * 2);
1164 1164
1165 early_trap_init(vectors); 1165 early_trap_init(vectors);
1166 1166
@@ -1210,10 +1210,18 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
1210 1210
1211 if (!vectors_high()) { 1211 if (!vectors_high()) {
1212 map.virtual = 0; 1212 map.virtual = 0;
1213 map.length = PAGE_SIZE * 2;
1213 map.type = MT_LOW_VECTORS; 1214 map.type = MT_LOW_VECTORS;
1214 create_mapping(&map); 1215 create_mapping(&map);
1215 } 1216 }
1216 1217
1218 /* Now create a kernel read-only mapping */
1219 map.pfn += 1;
1220 map.virtual = 0xffff0000 + PAGE_SIZE;
1221 map.length = PAGE_SIZE;
1222 map.type = MT_LOW_VECTORS;
1223 create_mapping(&map);
1224
1217 /* 1225 /*
1218 * Ask the machine support to map in the statically mapped devices. 1226 * Ask the machine support to map in the statically mapped devices.
1219 */ 1227 */