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

Commit b10bca0b authored by Will Deacon's avatar Will Deacon Committed by Russell King
Browse files

ARM: 7595/1: syscall: rework ordering in syscall_trace_exit



syscall_trace_exit is currently doing things back-to-front; invoking
the audit hook *after* signalling the debugger, which presents an
opportunity for the registers to be re-written by userspace in order to
bypass auditing constaints.

This patch fixes the ordering by moving the audit code first and the
tracehook code last. On the face of it, it looks like
current_thread_info()->syscall may be incorrect for the sys_exit
tracepoint, but that's actually not an issue because it will have been
set during syscall entry and cannot have changed since then.

Reported-by: default avatarAndrew Gabbasov <Andrew_Gabbasov@mentor.com>
Tested-by: default avatarMark Rutland <mark.rutland@arm.com>
Signed-off-by: default avatarWill Deacon <will.deacon@arm.com>
Signed-off-by: default avatarRussell King <rmk+kernel@arm.linux.org.uk>
parent 39b175a0
Loading
Loading
Loading
Loading
+0 −1
Original line number Original line Diff line number Diff line
@@ -455,7 +455,6 @@ __sys_trace:


__sys_trace_return:
__sys_trace_return:
	str	r0, [sp, #S_R0 + S_OFF]!	@ save returned r0
	str	r0, [sp, #S_R0 + S_OFF]!	@ save returned r0
	mov	r1, scno
	mov	r0, sp
	mov	r0, sp
	bl	syscall_trace_exit
	bl	syscall_trace_exit
	b	ret_slow_syscall
	b	ret_slow_syscall
+15 −9
Original line number Original line Diff line number Diff line
@@ -957,17 +957,23 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs, int scno)
	return scno;
	return scno;
}
}


asmlinkage int syscall_trace_exit(struct pt_regs *regs, int scno)
asmlinkage void syscall_trace_exit(struct pt_regs *regs)
{
{
	current_thread_info()->syscall = scno;
	/*

	 * Audit the syscall before anything else, as a debugger may
	if (test_thread_flag(TIF_SYSCALL_TRACE))
	 * come in and change the current registers.
		scno = tracehook_report_syscall(regs, PTRACE_SYSCALL_EXIT);
	 */
	audit_syscall_exit(regs);


	/*
	 * Note that we haven't updated the ->syscall field for the
	 * current thread. This isn't a problem because it will have
	 * been set on syscall entry and there hasn't been an opportunity
	 * for a PTRACE_SET_SYSCALL since then.
	 */
	if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
	if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
		trace_sys_exit(regs, scno);
		trace_sys_exit(regs, regs_return_value(regs));

	audit_syscall_exit(regs);


	return scno;
	if (test_thread_flag(TIF_SYSCALL_TRACE))
		tracehook_report_syscall(regs, PTRACE_SYSCALL_EXIT);
}
}