From 59ccb7b6e814964baccb39cf312bc9ecc42877e2 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Sun, 27 Jul 2008 16:51:03 +1000 Subject: [PATCH] --- yaml --- r: 106887 b: refs/heads/master c: 4f72c4279eab1e5f3ed1ac4e55d4527617582392 h: refs/heads/master i: 106885: 873e5027c9ddcc4512f3a25c64f7ecea86325374 106883: 22401c25a1d7b6decdd8975b39013f8fcf6ce4d6 106879: c36e86c5c9a774546c7e7a32c36cd20b2a5db96f v: v3 --- [refs] | 2 +- trunk/arch/powerpc/kernel/entry_32.S | 7 ++++- trunk/arch/powerpc/kernel/entry_64.S | 7 ++++- trunk/arch/powerpc/kernel/ptrace.c | 47 +++++++++++++--------------- 4 files changed, 35 insertions(+), 28 deletions(-) diff --git a/[refs] b/[refs] index cfb40f7e964e..7b6102686ae1 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 6558ba2b5cc3a2f22039db30616fcd07c1b28ac8 +refs/heads/master: 4f72c4279eab1e5f3ed1ac4e55d4527617582392 diff --git a/trunk/arch/powerpc/kernel/entry_32.S b/trunk/arch/powerpc/kernel/entry_32.S index da52269aec1e..e6fca6a9014d 100644 --- a/trunk/arch/powerpc/kernel/entry_32.S +++ b/trunk/arch/powerpc/kernel/entry_32.S @@ -343,7 +343,12 @@ syscall_dotrace: stw r0,_TRAP(r1) addi r3,r1,STACK_FRAME_OVERHEAD bl do_syscall_trace_enter - lwz r0,GPR0(r1) /* Restore original registers */ + /* + * Restore argument registers possibly just changed. + * We use the return value of do_syscall_trace_enter + * for call number to look up in the table (r0). + */ + mr r0,r3 lwz r3,GPR3(r1) lwz r4,GPR4(r1) lwz r5,GPR5(r1) diff --git a/trunk/arch/powerpc/kernel/entry_64.S b/trunk/arch/powerpc/kernel/entry_64.S index d7369243ae44..79c089e97ce4 100644 --- a/trunk/arch/powerpc/kernel/entry_64.S +++ b/trunk/arch/powerpc/kernel/entry_64.S @@ -214,7 +214,12 @@ syscall_dotrace: bl .save_nvgprs addi r3,r1,STACK_FRAME_OVERHEAD bl .do_syscall_trace_enter - ld r0,GPR0(r1) /* Restore original registers */ + /* + * Restore argument registers possibly just changed. + * We use the return value of do_syscall_trace_enter + * for the call number to look up in the table (r0). + */ + mr r0,r3 ld r3,GPR3(r1) ld r4,GPR4(r1) ld r5,GPR5(r1) diff --git a/trunk/arch/powerpc/kernel/ptrace.c b/trunk/arch/powerpc/kernel/ptrace.c index 66204cb51a1a..6b66cd85b433 100644 --- a/trunk/arch/powerpc/kernel/ptrace.c +++ b/trunk/arch/powerpc/kernel/ptrace.c @@ -22,6 +22,7 @@ #include #include #include +#include #include #include #include @@ -1014,31 +1015,24 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) return ret; } -static void do_syscall_trace(void) +/* + * We must return the syscall number to actually look up in the table. + * This can be -1L to skip running any syscall at all. + */ +long do_syscall_trace_enter(struct pt_regs *regs) { - /* 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) - ? 0x80 : 0)); - - /* - * this isn't the same as continuing with a signal, but it will do - * for normal use. strace only continues with a signal if the - * stopping signal is not SIGTRAP. -brl - */ - if (current->exit_code) { - send_sig(current->exit_code, current, 1); - current->exit_code = 0; - } -} + long ret = 0; -void do_syscall_trace_enter(struct pt_regs *regs) -{ secure_computing(regs->gpr[0]); - if (test_thread_flag(TIF_SYSCALL_TRACE) - && (current->ptrace & PT_PTRACED)) - do_syscall_trace(); + if (test_thread_flag(TIF_SYSCALL_TRACE) && + tracehook_report_syscall_entry(regs)) + /* + * Tracing decided this syscall should not happen. + * We'll return a bogus call number to get an ENOSYS + * error, but leave the original number in regs->gpr[0]. + */ + ret = -1L; if (unlikely(current->audit_context)) { #ifdef CONFIG_PPC64 @@ -1056,16 +1050,19 @@ void do_syscall_trace_enter(struct pt_regs *regs) regs->gpr[5] & 0xffffffff, regs->gpr[6] & 0xffffffff); } + + return ret ?: regs->gpr[0]; } void do_syscall_trace_leave(struct pt_regs *regs) { + int step; + if (unlikely(current->audit_context)) audit_syscall_exit((regs->ccr&0x10000000)?AUDITSC_FAILURE:AUDITSC_SUCCESS, regs->result); - if ((test_thread_flag(TIF_SYSCALL_TRACE) - || test_thread_flag(TIF_SINGLESTEP)) - && (current->ptrace & PT_PTRACED)) - do_syscall_trace(); + step = test_thread_flag(TIF_SINGLESTEP); + if (step || test_thread_flag(TIF_SYSCALL_TRACE)) + tracehook_report_syscall_exit(regs, step); }