summaryrefslogtreecommitdiff
path: root/arch/arm/kernel
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2012-05-04 17:52:02 +0100
committerVarun Wadekar <vwadekar@nvidia.com>2012-05-18 15:58:50 +0530
commitf3e3072a1aa6c0f53933c64ec0a492f2274b78b6 (patch)
treeca6f845ce911ae15bd4169542cf99c9ecc93e6de /arch/arm/kernel
parent498153940b0cec30cf2a7185a1726c46d430f03e (diff)
ARM: 7411/1: audit: fix treatment of saved ip register during syscall tracing
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: stable@vger.kernel.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>
Diffstat (limited to 'arch/arm/kernel')
-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 80abafb9bf33..d8dbe9ca66b0 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -916,14 +916,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,
@@ -936,6 +929,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)