Commit 9e270862 authored by Christophe Leroy's avatar Christophe Leroy Committed by Michael Ellerman
Browse files

powerpc/32: Warn and return ENOSYS on syscalls from kernel



Since commit b86fb888 ("powerpc/32: implement fast entry for
syscalls on non BOOKE") and commit 1a4b739b ("powerpc/32:
implement fast entry for syscalls on BOOKE"), syscalls from
kernel are unexpected and can have catastrophic consequences
as it will destroy the kernel stack.

Test MSR_PR on syscall entry. In case syscall is from kernel,
emit a warning and return ENOSYS error.

Signed-off-by: default avatarChristophe Leroy <christophe.leroy@c-s.fr>
Signed-off-by: default avatarMichael Ellerman <mpe@ellerman.id.au>
Link: https://lore.kernel.org/r/8ee3bdbbdfdfc64ca7001e90c43b2aee6f333578.1580470482.git.christophe.leroy@c-s.fr
parent 030e3474
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -575,6 +575,33 @@ syscall_exit_work:
	bl	do_syscall_trace_leave
	b	ret_from_except_full

	/*
	 * System call was called from kernel. We get here with SRR1 in r9.
	 * Mark the exception as recoverable once we have retrieved SRR0,
	 * trap a warning and return ENOSYS with CR[SO] set.
	 */
	.globl	ret_from_kernel_syscall
ret_from_kernel_syscall:
	mfspr	r9, SPRN_SRR0
	mfspr	r10, SPRN_SRR1
#if !defined(CONFIG_4xx) && !defined(CONFIG_BOOKE)
	LOAD_REG_IMMEDIATE(r11, MSR_KERNEL & ~(MSR_IR|MSR_DR))
	mtmsr	r11
#endif

0:	trap
	EMIT_BUG_ENTRY 0b,__FILE__,__LINE__, BUGFLAG_WARNING

	li	r3, ENOSYS
	crset	so
#if defined(CONFIG_PPC_8xx) && defined(CONFIG_PERF_EVENTS)
	mtspr	SPRN_NRI, r0
#endif
	mtspr	SPRN_SRR0, r9
	mtspr	SPRN_SRR1, r10
	SYNC
	RFI

/*
 * The fork/clone functions need to copy the full register set into
 * the child process. Therefore we need to save all the nonvolatile
+9 −7
Original line number Diff line number Diff line
@@ -111,14 +111,16 @@

.macro SYSCALL_ENTRY trapno
	mfspr	r12,SPRN_SPRG_THREAD
	mfspr	r9, SPRN_SRR1
#ifdef CONFIG_VMAP_STACK
	mfspr	r9, SPRN_SRR0
	mfspr	r11, SPRN_SRR1
	stw	r9, SRR0(r12)
	stw	r11, SRR1(r12)
	mfspr	r11, SPRN_SRR0
	stw	r11, SRR0(r12)
	stw	r9, SRR1(r12)
#endif
	mfcr	r10
	andi.	r11, r9, MSR_PR
	lwz	r11,TASK_STACK-THREAD(r12)
	beq-	99f
	rlwinm	r10,r10,0,4,2	/* Clear SO bit in CR */
	addi	r11, r11, THREAD_SIZE - INT_FRAME_SIZE
#ifdef CONFIG_VMAP_STACK
@@ -128,15 +130,14 @@
#endif
	tovirt_vmstack r12, r12
	tophys_novmstack r11, r11
	mflr	r9
	stw	r10,_CCR(r11)		/* save registers */
	stw	r9, _LINK(r11)
	mflr	r10
	stw	r10, _LINK(r11)
#ifdef CONFIG_VMAP_STACK
	lwz	r10, SRR0(r12)
	lwz	r9, SRR1(r12)
#else
	mfspr	r10,SPRN_SRR0
	mfspr	r9,SPRN_SRR1
#endif
	stw	r1,GPR1(r11)
	stw	r1,0(r11)
@@ -209,6 +210,7 @@
	mtspr	SPRN_SRR0,r11
	SYNC
	RFI				/* jump to handler, enable MMU */
99:	b	ret_from_kernel_syscall
.endm

.macro save_dar_dsisr_on_stack reg1, reg2, sp
+4 −1
Original line number Diff line number Diff line
@@ -104,16 +104,18 @@ FTR_SECTION_ELSE
#ifdef CONFIG_KVM_BOOKE_HV
ALT_FTR_SECTION_END_IFSET(CPU_FTR_EMB_HV)
#endif
	mfspr	r9, SPRN_SRR1
	BOOKE_CLEAR_BTB(r11)
	andi.	r11, r9, MSR_PR
	lwz	r11, TASK_STACK - THREAD(r10)
	rlwinm	r12,r12,0,4,2	/* Clear SO bit in CR */
	beq-	99f
	ALLOC_STACK_FRAME(r11, THREAD_SIZE - INT_FRAME_SIZE)
	stw	r12, _CCR(r11)		/* save various registers */
	mflr	r12
	stw	r12,_LINK(r11)
	mfspr	r12,SPRN_SRR0
	stw	r1, GPR1(r11)
	mfspr	r9,SPRN_SRR1
	stw	r1, 0(r11)
	mr	r1, r11
	stw	r12,_NIP(r11)
@@ -176,6 +178,7 @@ ALT_FTR_SECTION_END_IFSET(CPU_FTR_EMB_HV)
	mtspr	SPRN_SRR0,r11
	SYNC
	RFI				/* jump to handler, enable MMU */
99:	b	ret_from_kernel_syscall
.endm

/* To handle the additional exception priority levels on 40x and Book-E