[ARM] 3262/4: allow ptraced syscalls to be overriden

Patch from Nicolas Pitre

This is needed by strace to properly handle the tracing of some system
calls. It could be useful for other applications as well.

Based on an earlier patch from Daniel Jacobowitz.

Signed-off-by: Nicolas Pitre <nico@cam.org>
Signed-off-by: Daniel Jacobowitz <dan@debian.org>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>

authored by Nicolas Pitre and committed by Russell King 3f471126 6c90c872

+18 -3
+3
arch/arm/kernel/entry-common.S
··· 214 214 * context switches, and waiting for our parent to respond. 215 215 */ 216 216 __sys_trace: 217 + mov r2, scno 217 218 add r1, sp, #S_OFF 218 219 mov r0, #0 @ trace entry [IP = 0] 219 220 bl syscall_trace 220 221 221 222 adr lr, __sys_trace_return @ return address 223 + mov scno, r0 @ syscall number (possibly new) 222 224 add r1, sp, #S_R0 + S_OFF @ pointer to regs 223 225 cmp scno, #NR_syscalls @ check upper syscall limit 224 226 ldmccia r1, {r0 - r3} @ have to reload r0 - r3 ··· 229 227 230 228 __sys_trace_return: 231 229 str r0, [sp, #S_R0 + S_OFF]! @ save returned r0 230 + mov r2, scno 232 231 mov r1, sp 233 232 mov r0, #1 @ trace exit [IP = 1] 234 233 bl syscall_trace
+12 -3
arch/arm/kernel/ptrace.c
··· 766 766 (unsigned long __user *) data); 767 767 break; 768 768 769 + case PTRACE_SET_SYSCALL: 770 + ret = 0; 771 + child->ptrace_message = data; 772 + break; 773 + 769 774 default: 770 775 ret = ptrace_request(child, request, addr, data); 771 776 break; ··· 779 774 return ret; 780 775 } 781 776 782 - asmlinkage void syscall_trace(int why, struct pt_regs *regs) 777 + asmlinkage int syscall_trace(int why, struct pt_regs *regs, int scno) 783 778 { 784 779 unsigned long ip; 785 780 786 781 if (!test_thread_flag(TIF_SYSCALL_TRACE)) 787 - return; 782 + return scno; 788 783 if (!(current->ptrace & PT_PTRACED)) 789 - return; 784 + return scno; 790 785 791 786 /* 792 787 * Save IP. IP is used to denote syscall entry/exit: ··· 794 789 */ 795 790 ip = regs->ARM_ip; 796 791 regs->ARM_ip = why; 792 + 793 + current->ptrace_message = scno; 797 794 798 795 /* the 0x80 provides a way for the tracing parent to distinguish 799 796 between a syscall stop and SIGTRAP delivery */ ··· 811 804 current->exit_code = 0; 812 805 } 813 806 regs->ARM_ip = ip; 807 + 808 + return current->ptrace_message; 814 809 }
+3
include/asm-arm/ptrace.h
··· 23 23 #define PTRACE_OLDSETOPTIONS 21 24 24 25 25 #define PTRACE_GET_THREAD_AREA 22 26 + 27 + #define PTRACE_SET_SYSCALL 23 28 + 26 29 /* 27 30 * PSR bits 28 31 */