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

Commit 8bafae20 authored by Russell King's avatar Russell King
Browse files

ARM: BUG if jumping to usermode address in kernel mode



Detect if we are returning to usermode via the normal kernel exit paths
but the saved PSR value indicates that we are in kernel mode.  This
could occur due to corrupted stack state, which has been observed with
"ftracetest".

This ensures that we catch the problem case before we get to user code.

Signed-off-by: default avatarRussell King <rmk+kernel@armlinux.org.uk>
parent 400eeffa
Loading
Loading
Loading
Loading
+18 −0
Original line number Original line Diff line number Diff line
@@ -518,4 +518,22 @@ THUMB( orr \reg , \reg , #PSR_T_BIT )
#endif
#endif
	.endm
	.endm


	.macro	bug, msg, line
#ifdef CONFIG_THUMB2_KERNEL
1:	.inst	0xde02
#else
1:	.inst	0xe7f001f2
#endif
#ifdef CONFIG_DEBUG_BUGVERBOSE
	.pushsection .rodata.str, "aMS", %progbits, 1
2:	.asciz	"\msg"
	.popsection
	.pushsection __bug_table, "aw"
	.align	2
	.word	1b, 2b
	.hword	\line
	.popsection
#endif
	.endm

#endif /* __ASM_ASSEMBLER_H__ */
#endif /* __ASM_ASSEMBLER_H__ */
+6 −0
Original line number Original line Diff line number Diff line
@@ -299,6 +299,8 @@
	mov	r2, sp
	mov	r2, sp
	ldr	r1, [r2, #\offset + S_PSR]	@ get calling cpsr
	ldr	r1, [r2, #\offset + S_PSR]	@ get calling cpsr
	ldr	lr, [r2, #\offset + S_PC]!	@ get pc
	ldr	lr, [r2, #\offset + S_PC]!	@ get pc
	tst	r1, #0xcf
	bne	1f
	msr	spsr_cxsf, r1			@ save in spsr_svc
	msr	spsr_cxsf, r1			@ save in spsr_svc
#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_32v6K)
#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_32v6K)
	@ We must avoid clrex due to Cortex-A15 erratum #830321
	@ We must avoid clrex due to Cortex-A15 erratum #830321
@@ -313,6 +315,7 @@
						@ after ldm {}^
						@ after ldm {}^
	add	sp, sp, #\offset + PT_REGS_SIZE
	add	sp, sp, #\offset + PT_REGS_SIZE
	movs	pc, lr				@ return & move spsr_svc into cpsr
	movs	pc, lr				@ return & move spsr_svc into cpsr
1:	bug	"Returning to usermode but unexpected PSR bits set?", \@
#elif defined(CONFIG_CPU_V7M)
#elif defined(CONFIG_CPU_V7M)
	@ V7M restore.
	@ V7M restore.
	@ Note that we don't need to do clrex here as clearing the local
	@ Note that we don't need to do clrex here as clearing the local
@@ -328,6 +331,8 @@
	ldr	r1, [sp, #\offset + S_PSR]	@ get calling cpsr
	ldr	r1, [sp, #\offset + S_PSR]	@ get calling cpsr
	ldr	lr, [sp, #\offset + S_PC]	@ get pc
	ldr	lr, [sp, #\offset + S_PC]	@ get pc
	add	sp, sp, #\offset + S_SP
	add	sp, sp, #\offset + S_SP
	tst	r1, #0xcf
	bne	1f
	msr	spsr_cxsf, r1			@ save in spsr_svc
	msr	spsr_cxsf, r1			@ save in spsr_svc


	@ We must avoid clrex due to Cortex-A15 erratum #830321
	@ We must avoid clrex due to Cortex-A15 erratum #830321
@@ -340,6 +345,7 @@
	.endif
	.endif
	add	sp, sp, #PT_REGS_SIZE - S_SP
	add	sp, sp, #PT_REGS_SIZE - S_SP
	movs	pc, lr				@ return & move spsr_svc into cpsr
	movs	pc, lr				@ return & move spsr_svc into cpsr
1:	bug	"Returning to usermode but unexpected PSR bits set?", \@
#endif	/* !CONFIG_THUMB2_KERNEL */
#endif	/* !CONFIG_THUMB2_KERNEL */
	.endm
	.endm