Home Home > GIT Browse
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2012-05-04 17:52:02 +0100
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-05-12 09:32:09 -0700
commit50f764acf24996dc3fd845f837f88a80b80b7d53 (patch)
tree875c34f0bf91360936cf78d3d652cf4f8e32aafa
parentacfee6ae4cf54e4afb10252c86dc72ca3472eec7 (diff)
ARM: 7411/1: audit: fix treatment of saved ip register during syscall tracing
commit 6a68b6f574c8ad2c1d90f0db8fd95b8abe8a0a73 upstream. The ARM audit code incorrectly uses the saved application ip register value to infer syscall entry or exit. Additionally, the saved value will be clobbered if the current task is not being traced, which can lead to libc corruption if ip is live (apparently glibc uses it for the TLS pointer). This patch fixes the syscall tracing code so that the why parameter is used to infer the syscall direction and the saved ip is only updated if we know that we will be signalling a ptrace trap. Reported-and-Tested-by: Jon Masters <jcm@jonmasters.org> Cc: Eric Paris <eparis@redhat.com> Signed-off-by: Will Deacon <will.deacon@arm.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--arch/arm/kernel/ptrace.c16
1 files changed, 8 insertions, 8 deletions
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index ede6443c34d9..b139270a30fe 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -915,14 +915,7 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno)
{
unsigned long ip;
- /*
- * Save IP. IP is used to denote syscall entry/exit:
- * IP = 0 -> entry, = 1 -> exit
- */
- ip = regs->ARM_ip;
- regs->ARM_ip = why;
-
- if (!ip)
+ if (why)
audit_syscall_exit(regs);
else
audit_syscall_entry(AUDIT_ARCH_NR, scno, regs->ARM_r0,
@@ -935,6 +928,13 @@ asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno)
current_thread_info()->syscall = scno;
+ /*
+ * IP is used to denote syscall entry/exit:
+ * IP = 0 -> entry, =1 -> exit
+ */
+ ip = regs->ARM_ip;
+ regs->ARM_ip = why;
+
/* the 0x80 provides a way for the tracing parent to distinguish
between a syscall stop and SIGTRAP delivery */
ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)