Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit d303fa12 authored by Russell King's avatar Russell King Committed by Joonwoo Park
Browse files

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: default avatarNicolas Pitre <nico@linaro.org>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
Git-commit: 19accfd373847ac3d10623c5d20f948846299741
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git



ARM: use linker magic for vectors and vector stubs

Use linker magic to create the vectors and vector stubs: we can tell the
linker to place them at an appropriate VMA, but keep the LMA within the
kernel.  This gets rid of some unnecessary symbol manipulation, and
have the linker calculate the relocations appropriately.

Change-Id: I694f6b651e60fccd7e3c818f981a3883f9c212de
Cc: <stable@vger.kernel.org>
Acked-by: default avatarNicolas Pitre <nico@linaro.org>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
Git-commit: b9b32bf70f2fb710b07c94e13afbc729afe221da
Git-repo: git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git


[joonwoop@codeaurora.org: squashed 19accfd and b9b32bf because 19accfd
			broke build]
Signed-off-by: default avatarJoonwoo Park <joonwoop@codeaurora.org>
parent 2b6a9b84
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -216,7 +216,8 @@ config VECTORS_BASE
	default DRAM_BASE if REMAP_VECTORS_TO_RAM
	default 0x00000000
	help
	  The base address of exception vectors.
	  The base address of exception vectors.  This must be two pages
	  in size.

config ARM_PATCH_PHYS_VIRT
	bool "Patch physical to virtual translations at runtime" if EMBEDDED
+32 −41
Original line number Diff line number Diff line
@@ -1035,9 +1035,9 @@ __kuser_helper_end:
/*
 * Vector stubs.
 *
 * This code is copied to 0xffff0200 so we can use branches in the
 * vectors, rather than ldr's.  Note that this code must not
 * exceed 0x300 bytes.
 * This code is copied to 0xffff1000 so we can use branches in the
 * vectors, rather than ldr's.  Note that this code must not exceed
 * a page size.
 *
 * Common stub entry macro:
 *   Enter in IRQ mode, spsr = SVC/USR CPSR, lr = SVC/USR PC
@@ -1096,8 +1096,17 @@ ENDPROC(vector_\name)
1:
	.endm

	.globl	__stubs_start
	.section .stubs, "ax", %progbits
__stubs_start:
	@ This must be the first word
	.word	vector_swi

vector_rst:
 ARM(	swi	SYS_ERROR0	)
 THUMB(	svc	#0		)
 THUMB(	nop			)
	b	vector_und

/*
 * Interrupt dispatcher
 */
@@ -1191,6 +1200,16 @@ __stubs_start:

	.align	5

/*=============================================================================
 * Address exception handler
 *-----------------------------------------------------------------------------
 * These aren't too critical.
 * (they're not supposed to happen, and won't happen in 32-bit data mode).
 */

vector_addrexcptn:
	b	vector_addrexcptn

/*=============================================================================
 * Undefined FIQs
 *-----------------------------------------------------------------------------
@@ -1204,47 +1223,19 @@ __stubs_start:
vector_fiq:
	subs	pc, lr, #4

/*=============================================================================
 * Address exception handler
 *-----------------------------------------------------------------------------
 * These aren't too critical.
 * (they're not supposed to happen, and won't happen in 32-bit data mode).
 */

vector_addrexcptn:
	b	vector_addrexcptn

/*
 * We group all the following data together to optimise
 * for CPUs with separate I & D caches.
 */
	.align	5

.LCvswi:
	.word	vector_swi
.krait_fixup:
	.word	msm_krait_need_wfe_fixup

	.globl	__stubs_end
__stubs_end:

	.equ	stubs_offset, __vectors_start + 0x200 - __stubs_start

	.globl	__vectors_start
	.section .vectors, "ax", %progbits
__vectors_start:
 ARM(	swi	SYS_ERROR0	)
 THUMB(	svc	#0		)
 THUMB(	nop			)
	W(b)	vector_und + stubs_offset
	W(ldr)	pc, .LCvswi + stubs_offset
	W(b)	vector_pabt + stubs_offset
	W(b)	vector_dabt + stubs_offset
	W(b)	vector_addrexcptn + stubs_offset
	W(b)	vector_irq + stubs_offset
	W(b)	vector_fiq + stubs_offset

	.globl	__vectors_end
__vectors_end:
	W(b)	vector_rst
	W(b)	vector_und
	W(ldr)	pc, __vectors_start + 0x1000
	W(b)	vector_pabt
	W(b)	vector_dabt
	W(b)	vector_addrexcptn
	W(b)	vector_irq
	W(b)	vector_fiq

	.data

+2 −2
Original line number Diff line number Diff line
@@ -840,7 +840,7 @@ void __init early_trap_init(void *vectors_base)
	 * are visible to the instruction stream.
	 */
	memcpy((void *)vectors, __vectors_start, __vectors_end - __vectors_start);
	memcpy((void *)vectors + 0x200, __stubs_start, __stubs_end - __stubs_start);
	memcpy((void *)vectors + 0x1000, __stubs_start, __stubs_end - __stubs_start);
	memcpy((void *)vectors + 0x1000 - kuser_sz, __kuser_helper_start, kuser_sz);

	/*
@@ -855,6 +855,6 @@ void __init early_trap_init(void *vectors_base)
	memcpy((void *)(vectors + KERN_SIGRETURN_CODE - CONFIG_VECTORS_BASE),
	       sigreturn_codes, sizeof(sigreturn_codes));

	flush_icache_range(vectors, vectors + PAGE_SIZE);
	flush_icache_range(vectors, vectors + PAGE_SIZE * 2);
	modify_domain(DOMAIN_USER, DOMAIN_CLIENT);
}
+17 −0
Original line number Diff line number Diff line
@@ -166,6 +166,23 @@ SECTIONS
#endif
	__init_begin = .;
#endif
	/*
	 * The vectors and stubs are relocatable code, and the
	 * only thing that matters is their relative offsets
	 */
	__vectors_start = .;
	.vectors 0 : AT(__vectors_start) {
		*(.vectors)
	}
	. = __vectors_start + SIZEOF(.vectors);
	__vectors_end = .;

	__stubs_start = .;
	.stubs 0x1000 : AT(__stubs_start) {
		*(.stubs)
	}
	. = __stubs_start + SIZEOF(.stubs);
	__stubs_end = .;

	INIT_TEXT_SECTION(8)
	.exit.text : {
+9 −1
Original line number Diff line number Diff line
@@ -1290,7 +1290,7 @@ static void __init devicemaps_init(struct machine_desc *mdesc)
	/*
	 * Allocate the vector page early.
	 */
	vectors = early_alloc(PAGE_SIZE);
	vectors = early_alloc(PAGE_SIZE * 2);

	early_trap_init(vectors);

@@ -1340,10 +1340,18 @@ static void __init devicemaps_init(struct machine_desc *mdesc)

	if (!vectors_high()) {
		map.virtual = 0;
		map.length = PAGE_SIZE * 2;
		map.type = MT_LOW_VECTORS;
		create_mapping(&map);
	}

	/* Now create a kernel read-only mapping */
	map.pfn += 1;
	map.virtual = 0xffff0000 + PAGE_SIZE;
	map.length = PAGE_SIZE;
	map.type = MT_LOW_VECTORS;
	create_mapping(&map);

	/*
	 * Ask the machine support to map in the statically mapped devices.
	 */