Commit 00fdec98 authored by Vineet Gupta's avatar Vineet Gupta
Browse files

ARC: entry: fix potential EFA clobber when TIF_SYSCALL_TRACE



Trap handler for syscall tracing reads EFA (Exception Fault Address),
in case strace wants PC of trap instruction (EFA is not part of pt_regs
as of current code).

However this EFA read is racy as it happens after dropping to pure
kernel mode (re-enabling interrupts). A taken interrupt could
context-switch, trigger a different task's trap, clobbering EFA for this
execution context.

Fix this by reading EFA early, before re-enabling interrupts. A slight
side benefit is de-duplication of FAKE_RET_FROM_EXCPN in trap handler.
The trap handler is common to both ARCompact and ARCv2 builds too.

This just came out of code rework/review and no real problem was reported
but is clearly a potential problem specially for strace.

Cc: <stable@vger.kernel.org>
Signed-off-by: default avatarVineet Gupta <vgupta@synopsys.com>
parent b3a9e3b9
Loading
Loading
Loading
Loading
+5 −11
Original line number Diff line number Diff line
@@ -165,7 +165,6 @@ END(EV_Extension)
tracesys:
	; save EFA in case tracer wants the PC of traced task
	; using ERET won't work since next-PC has already committed
	lr  r12, [efa]
	GET_CURR_TASK_FIELD_PTR   TASK_THREAD, r11
	st  r12, [r11, THREAD_FAULT_ADDR]	; thread.fault_address

@@ -208,15 +207,9 @@ tracesys_exit:
; Breakpoint TRAP
; ---------------------------------------------
trap_with_param:

	; stop_pc info by gdb needs this info
	lr  r0, [efa]
	mov r0, r12	; EFA in case ptracer/gdb wants stop_pc
	mov r1, sp

	; Now that we have read EFA, it is safe to do "fake" rtie
	;   and get out of CPU exception mode
	FAKE_RET_FROM_EXCPN

	; Save callee regs in case gdb wants to have a look
	; SP will grow up by size of CALLEE Reg-File
	; NOTE: clobbers r12
@@ -243,6 +236,10 @@ ENTRY(EV_Trap)

	EXCEPTION_PROLOGUE

	lr  r12, [efa]

	FAKE_RET_FROM_EXCPN

	;============ TRAP 1   :breakpoints
	; Check ECR for trap with arg (PROLOGUE ensures r10 has ECR)
	bmsk.f 0, r10, 7
@@ -250,9 +247,6 @@ ENTRY(EV_Trap)

	;============ TRAP  (no param): syscall top level

	; First return from Exception to pure K mode (Exception/IRQs renabled)
	FAKE_RET_FROM_EXCPN

	; If syscall tracing ongoing, invoke pre-post-hooks
	GET_CURR_THR_INFO_FLAGS   r10
	btst r10, TIF_SYSCALL_TRACE