Skip to content

Commit 8bafae2

Browse files
author
Russell King
committed
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: Russell King <rmk+kernel@armlinux.org.uk>
1 parent 400eeff commit 8bafae2

File tree

2 files changed

+24
-0
lines changed

2 files changed

+24
-0
lines changed

arch/arm/include/asm/assembler.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -518,4 +518,22 @@ THUMB( orr \reg , \reg , #PSR_T_BIT )
518518
#endif
519519
.endm
520520

521+
.macro bug, msg, line
522+
#ifdef CONFIG_THUMB2_KERNEL
523+
1: .inst 0xde02
524+
#else
525+
1: .inst 0xe7f001f2
526+
#endif
527+
#ifdef CONFIG_DEBUG_BUGVERBOSE
528+
.pushsection .rodata.str, "aMS", %progbits, 1
529+
2: .asciz "\msg"
530+
.popsection
531+
.pushsection __bug_table, "aw"
532+
.align 2
533+
.word 1b, 2b
534+
.hword \line
535+
.popsection
536+
#endif
537+
.endm
538+
521539
#endif /* __ASM_ASSEMBLER_H__ */

arch/arm/kernel/entry-header.S

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -299,6 +299,8 @@
299299
mov r2, sp
300300
ldr r1, [r2, #\offset + S_PSR] @ get calling cpsr
301301
ldr lr, [r2, #\offset + S_PC]! @ get pc
302+
tst r1, #0xcf
303+
bne 1f
302304
msr spsr_cxsf, r1 @ save in spsr_svc
303305
#if defined(CONFIG_CPU_V6) || defined(CONFIG_CPU_32v6K)
304306
@ We must avoid clrex due to Cortex-A15 erratum #830321
@@ -313,6 +315,7 @@
313315
@ after ldm {}^
314316
add sp, sp, #\offset + PT_REGS_SIZE
315317
movs pc, lr @ return & move spsr_svc into cpsr
318+
1: bug "Returning to usermode but unexpected PSR bits set?", \@
316319
#elif defined(CONFIG_CPU_V7M)
317320
@ V7M restore.
318321
@ Note that we don't need to do clrex here as clearing the local
@@ -328,6 +331,8 @@
328331
ldr r1, [sp, #\offset + S_PSR] @ get calling cpsr
329332
ldr lr, [sp, #\offset + S_PC] @ get pc
330333
add sp, sp, #\offset + S_SP
334+
tst r1, #0xcf
335+
bne 1f
331336
msr spsr_cxsf, r1 @ save in spsr_svc
332337

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

0 commit comments

Comments
 (0)