aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/kernel/ptrace.c
diff options
context:
space:
mode:
authorWill Deacon <will.deacon@arm.com>2012-05-04 12:52:02 -0400
committerRussell King <rmk+kernel@arm.linux.org.uk>2012-05-05 08:54:01 -0400
commit6a68b6f574c8ad2c1d90f0db8fd95b8abe8a0a73 (patch)
tree0d279c6835622d461a35ee1a55ad62275d7e0520 /arch/arm/kernel/ptrace.c
parente787ec1376e862fcea1bfd523feb7c5fb43ecdb9 (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/ptrace.c')
-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)
916{ 916{
917 unsigned long ip; 917 unsigned long ip;
918 918
919 /* 919 if (why)
920 * Save IP. IP is used to denote syscall entry/exit:
921 * IP = 0 -> entry, = 1 -> exit
922 */
923 ip = regs->ARM_ip;
924 regs->ARM_ip = why;
925
926 if (!ip)
927 audit_syscall_exit(regs); 920 audit_syscall_exit(regs);
928 else 921 else
929 audit_syscall_entry(AUDIT_ARCH_NR, scno, regs->ARM_r0, 922 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)
936 929
937 current_thread_info()->syscall = scno; 930 current_thread_info()->syscall = scno;
938 931
932 /*
933 * IP is used to denote syscall entry/exit:
934 * IP = 0 -> entry, =1 -> exit
935 */
936 ip = regs->ARM_ip;
937 regs->ARM_ip = why;
938
939 /* the 0x80 provides a way for the tracing parent to distinguish 939 /* the 0x80 provides a way for the tracing parent to distinguish
940 between a syscall stop and SIGTRAP delivery */ 940 between a syscall stop and SIGTRAP delivery */
941 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) 941 ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)