X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=arch%2Fs390%2Fkernel%2Fptrace.c;h=9d3dcfa79ea26a7101321153b0a4880ce04586c9;hb=667000011927b4fcc359beac4a2447889db6d349;hp=c8b08289eb87e1d78c9c92996fe7bbfe30c16645;hpb=3d6e48f43340343d97839eadb1ab7b6a3ea98797;p=safe%2Fjmp%2Flinux-2.6 diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index c8b0828..9d3dcfa 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -35,7 +34,10 @@ #include #include #include - +#include +#include +#include +#include #include #include #include @@ -49,6 +51,9 @@ #include "compat_ptrace.h" #endif +DEFINE_TRACE(syscall_enter); +DEFINE_TRACE(syscall_exit); + enum s390_regset { REGSET_GENERAL, REGSET_FP, @@ -68,7 +73,7 @@ FixPerRegisters(struct task_struct *task) if (per_info->single_step) { per_info->control_regs.bits.starting_addr = 0; #ifdef CONFIG_COMPAT - if (test_thread_flag(TIF_31BIT)) + if (is_compat_task()) per_info->control_regs.bits.ending_addr = 0x7fffffffUL; else #endif @@ -203,7 +208,6 @@ static unsigned long __peek_user(struct task_struct *child, addr_t addr) static int peek_user(struct task_struct *child, addr_t addr, addr_t data) { - struct user *dummy = NULL; addr_t tmp, mask; /* @@ -212,8 +216,8 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data) */ mask = __ADDR_MASK; #ifdef CONFIG_64BIT - if (addr >= (addr_t) &dummy->regs.acrs && - addr < (addr_t) &dummy->regs.orig_gpr2) + if (addr >= (addr_t) &((struct user *) NULL)->regs.acrs && + addr < (addr_t) &((struct user *) NULL)->regs.orig_gpr2) mask = 3; #endif if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK) @@ -311,7 +315,6 @@ static int __poke_user(struct task_struct *child, addr_t addr, addr_t data) static int poke_user(struct task_struct *child, addr_t addr, addr_t data) { - struct user *dummy = NULL; addr_t mask; /* @@ -320,8 +323,8 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data) */ mask = __ADDR_MASK; #ifdef CONFIG_64BIT - if (addr >= (addr_t) &dummy->regs.acrs && - addr < (addr_t) &dummy->regs.orig_gpr2) + if (addr >= (addr_t) &((struct user *) NULL)->regs.acrs && + addr < (addr_t) &((struct user *) NULL)->regs.orig_gpr2) mask = 3; #endif if ((addr & mask) || addr > sizeof(struct user) - __ADDR_MASK) @@ -483,8 +486,7 @@ static int peek_user_compat(struct task_struct *child, { __u32 tmp; - if (!test_thread_flag(TIF_31BIT) || - (addr & 3) || addr > sizeof(struct user) - 3) + if (!is_compat_task() || (addr & 3) || addr > sizeof(struct user) - 3) return -EIO; tmp = __peek_user_compat(child, addr); @@ -585,8 +587,7 @@ static int __poke_user_compat(struct task_struct *child, static int poke_user_compat(struct task_struct *child, addr_t addr, addr_t data) { - if (!test_thread_flag(TIF_31BIT) || - (addr & 3) || addr > sizeof(struct user32) - 3) + if (!is_compat_task() || (addr & 3) || addr > sizeof(struct user32) - 3) return -EIO; return __poke_user_compat(child, addr, data); @@ -639,40 +640,53 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request, } #endif -asmlinkage void -syscall_trace(struct pt_regs *regs, int entryexit) +asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) { - if (unlikely(current->audit_context) && entryexit) - audit_syscall_exit(AUDITSC_RESULT(regs->gprs[2]), regs->gprs[2]); + long ret; - if (!test_thread_flag(TIF_SYSCALL_TRACE)) - goto out; - if (!(current->ptrace & PT_PTRACED)) - goto out; - ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) - ? 0x80 : 0)); + /* Do the secure computing check first. */ + secure_computing(regs->gprs[2]); /* - * If the debuffer has set an invalid system call number, - * we prepare to skip the system call restart handling. + * The sysc_tracesys code in entry.S stored the system + * call number to gprs[2]. */ - if (!entryexit && regs->gprs[2] >= NR_syscalls) - regs->trap = -1; - - /* - * 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; + ret = regs->gprs[2]; + if (test_thread_flag(TIF_SYSCALL_TRACE) && + (tracehook_report_syscall_entry(regs) || + regs->gprs[2] >= NR_syscalls)) { + /* + * Tracing decided this syscall should not happen or the + * debugger stored an invalid system call number. Skip + * the system call and the system call restart handling. + */ + regs->svcnr = 0; + ret = -1; } - out: - if (unlikely(current->audit_context) && !entryexit) - audit_syscall_entry(test_thread_flag(TIF_31BIT)?AUDIT_ARCH_S390:AUDIT_ARCH_S390X, - regs->gprs[2], regs->orig_gpr2, regs->gprs[3], - regs->gprs[4], regs->gprs[5]); + + if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) + trace_syscall_enter(regs, regs->gprs[2]); + + if (unlikely(current->audit_context)) + audit_syscall_entry(is_compat_task() ? + AUDIT_ARCH_S390 : AUDIT_ARCH_S390X, + regs->gprs[2], regs->orig_gpr2, + regs->gprs[3], regs->gprs[4], + regs->gprs[5]); + return ret; +} + +asmlinkage void do_syscall_trace_exit(struct pt_regs *regs) +{ + if (unlikely(current->audit_context)) + audit_syscall_exit(AUDITSC_RESULT(regs->gprs[2]), + regs->gprs[2]); + + if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) + trace_syscall_exit(regs, regs->gprs[2]); + + if (test_thread_flag(TIF_SYSCALL_TRACE)) + tracehook_report_syscall_exit(regs, 0); } /*