X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=arch%2Fs390%2Fkernel%2Fptrace.c;h=5a3bb177faf8048b8f66e1c330cb2ab235b89afb;hb=43bc926fffd92024b46cafaf7350d669ba9ca884;hp=3be331966b15f6af0a70abc07ebc06c80faef760;hpb=f7f1b0f1e2fbadeab12d24236000e778aa9b1ead;p=linux-2.6.git diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c index 3be331966..5a3bb177f 100644 --- a/arch/s390/kernel/ptrace.c +++ b/arch/s390/kernel/ptrace.c @@ -42,7 +42,7 @@ #include #include -#ifdef CONFIG_S390_SUPPORT +#ifdef CONFIG_COMPAT #include "compat_ptrace.h" #endif @@ -52,14 +52,14 @@ FixPerRegisters(struct task_struct *task) struct pt_regs *regs; per_struct *per_info; - regs = __KSTK_PTREGS(task); + regs = task_pt_regs(task); per_info = (per_struct *) &task->thread.per_info; per_info->control_regs.bits.em_instruction_fetch = per_info->single_step | per_info->instruction_fetch; if (per_info->single_step) { per_info->control_regs.bits.starting_addr = 0; -#ifdef CONFIG_S390_SUPPORT +#ifdef CONFIG_COMPAT if (test_thread_flag(TIF_31BIT)) per_info->control_regs.bits.ending_addr = 0x7fffffffUL; else @@ -112,7 +112,7 @@ ptrace_disable(struct task_struct *child) clear_single_step(child); } -#ifndef CONFIG_ARCH_S390X +#ifndef CONFIG_64BIT # define __ADDR_MASK 3 #else # define __ADDR_MASK 7 @@ -138,7 +138,7 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data) * an alignment of 4. Programmers from hell... */ mask = __ADDR_MASK; -#ifdef CONFIG_ARCH_S390X +#ifdef CONFIG_64BIT if (addr >= (addr_t) &dummy->regs.acrs && addr < (addr_t) &dummy->regs.orig_gpr2) mask = 3; @@ -150,7 +150,7 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data) /* * psw and gprs are stored on the stack */ - tmp = *(addr_t *)((addr_t) &__KSTK_PTREGS(child)->psw + addr); + tmp = *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr); if (addr == (addr_t) &dummy->regs.psw.mask) /* Remove per bit from user psw. */ tmp &= ~PSW_MASK_PER; @@ -160,7 +160,7 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data) * access registers are stored in the thread structure */ offset = addr - (addr_t) &dummy->regs.acrs; -#ifdef CONFIG_ARCH_S390X +#ifdef CONFIG_64BIT /* * Very special case: old & broken 64 bit gdb reading * from acrs[15]. Result is a 64 bit value. Read the @@ -176,7 +176,7 @@ peek_user(struct task_struct *child, addr_t addr, addr_t data) /* * orig_gpr2 is stored on the kernel stack */ - tmp = (addr_t) __KSTK_PTREGS(child)->orig_gpr2; + tmp = (addr_t) task_pt_regs(child)->orig_gpr2; } else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) { /* @@ -218,7 +218,7 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data) * an alignment of 4. Programmers from hell indeed... */ mask = __ADDR_MASK; -#ifdef CONFIG_ARCH_S390X +#ifdef CONFIG_64BIT if (addr >= (addr_t) &dummy->regs.acrs && addr < (addr_t) &dummy->regs.orig_gpr2) mask = 3; @@ -231,26 +231,26 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data) * psw and gprs are stored on the stack */ if (addr == (addr_t) &dummy->regs.psw.mask && -#ifdef CONFIG_S390_SUPPORT +#ifdef CONFIG_COMPAT data != PSW_MASK_MERGE(PSW_USER32_BITS, data) && #endif data != PSW_MASK_MERGE(PSW_USER_BITS, data)) /* Invalid psw mask. */ return -EINVAL; -#ifndef CONFIG_ARCH_S390X +#ifndef CONFIG_64BIT if (addr == (addr_t) &dummy->regs.psw.addr) /* I'd like to reject addresses without the high order bit but older gdb's rely on it */ data |= PSW_ADDR_AMODE; #endif - *(addr_t *)((addr_t) &__KSTK_PTREGS(child)->psw + addr) = data; + *(addr_t *)((addr_t) &task_pt_regs(child)->psw + addr) = data; } else if (addr < (addr_t) (&dummy->regs.orig_gpr2)) { /* * access registers are stored in the thread structure */ offset = addr - (addr_t) &dummy->regs.acrs; -#ifdef CONFIG_ARCH_S390X +#ifdef CONFIG_64BIT /* * Very special case: old & broken 64 bit gdb writing * to acrs[15] with a 64 bit value. Ignore the lower @@ -267,7 +267,7 @@ poke_user(struct task_struct *child, addr_t addr, addr_t data) /* * orig_gpr2 is stored on the kernel stack */ - __KSTK_PTREGS(child)->orig_gpr2 = data; + task_pt_regs(child)->orig_gpr2 = data; } else if (addr < (addr_t) (&dummy->regs.fp_regs + 1)) { /* @@ -357,7 +357,7 @@ do_ptrace_normal(struct task_struct *child, long request, long addr, long data) return ptrace_request(child, request, addr, data); } -#ifdef CONFIG_S390_SUPPORT +#ifdef CONFIG_COMPAT /* * Now the fun part starts... a 31 bit program running in the * 31 bit emulation tracing another program. PTRACE_PEEKTEXT, @@ -393,15 +393,15 @@ peek_user_emu31(struct task_struct *child, addr_t addr, addr_t data) */ if (addr == (addr_t) &dummy32->regs.psw.mask) { /* Fake a 31 bit psw mask. */ - tmp = (__u32)(__KSTK_PTREGS(child)->psw.mask >> 32); + tmp = (__u32)(task_pt_regs(child)->psw.mask >> 32); tmp = PSW32_MASK_MERGE(PSW32_USER_BITS, tmp); } else if (addr == (addr_t) &dummy32->regs.psw.addr) { /* Fake a 31 bit psw address. */ - tmp = (__u32) __KSTK_PTREGS(child)->psw.addr | + tmp = (__u32) task_pt_regs(child)->psw.addr | PSW32_ADDR_AMODE31; } else { /* gpr 0-15 */ - tmp = *(__u32 *)((addr_t) &__KSTK_PTREGS(child)->psw + + tmp = *(__u32 *)((addr_t) &task_pt_regs(child)->psw + addr*2 + 4); } } else if (addr < (addr_t) (&dummy32->regs.orig_gpr2)) { @@ -415,7 +415,7 @@ peek_user_emu31(struct task_struct *child, addr_t addr, addr_t data) /* * orig_gpr2 is stored on the kernel stack */ - tmp = *(__u32*)((addr_t) &__KSTK_PTREGS(child)->orig_gpr2 + 4); + tmp = *(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4); } else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) { /* @@ -472,15 +472,15 @@ poke_user_emu31(struct task_struct *child, addr_t addr, addr_t data) if (tmp != PSW32_MASK_MERGE(PSW32_USER_BITS, tmp)) /* Invalid psw mask. */ return -EINVAL; - __KSTK_PTREGS(child)->psw.mask = + task_pt_regs(child)->psw.mask = PSW_MASK_MERGE(PSW_USER32_BITS, (__u64) tmp << 32); } else if (addr == (addr_t) &dummy32->regs.psw.addr) { /* Build a 64 bit psw address from 31 bit address. */ - __KSTK_PTREGS(child)->psw.addr = + task_pt_regs(child)->psw.addr = (__u64) tmp & PSW32_ADDR_INSN; } else { /* gpr 0-15 */ - *(__u32*)((addr_t) &__KSTK_PTREGS(child)->psw + *(__u32*)((addr_t) &task_pt_regs(child)->psw + addr*2 + 4) = tmp; } } else if (addr < (addr_t) (&dummy32->regs.orig_gpr2)) { @@ -494,7 +494,7 @@ poke_user_emu31(struct task_struct *child, addr_t addr, addr_t data) /* * orig_gpr2 is stored on the kernel stack */ - *(__u32*)((addr_t) &__KSTK_PTREGS(child)->orig_gpr2 + 4) = tmp; + *(__u32*)((addr_t) &task_pt_regs(child)->orig_gpr2 + 4) = tmp; } else if (addr < (addr_t) (&dummy32->regs.fp_regs + 1)) { /* @@ -629,7 +629,7 @@ do_ptrace(struct task_struct *child, long request, long addr, long data) return peek_user(child, addr, data); if (request == PTRACE_POKEUSR && addr == PT_IEEE_IP) return poke_user(child, addr, data); -#ifdef CONFIG_S390_SUPPORT +#ifdef CONFIG_COMPAT if (request == PTRACE_PEEKUSR && addr == PT32_IEEE_IP && test_thread_flag(TIF_31BIT)) return peek_user_emu31(child, addr, data); @@ -695,7 +695,7 @@ do_ptrace(struct task_struct *child, long request, long addr, long data) /* Do requests that differ for 31/64 bit */ default: -#ifdef CONFIG_S390_SUPPORT +#ifdef CONFIG_COMPAT if (test_thread_flag(TIF_31BIT)) return do_ptrace_emu31(child, request, addr, data); #endif @@ -712,34 +712,21 @@ sys_ptrace(long request, long pid, long addr, long data) int ret; lock_kernel(); - if (request == PTRACE_TRACEME) { - /* are we already being traced? */ - ret = -EPERM; - if (current->ptrace & PT_PTRACED) - goto out; - ret = security_ptrace(current->parent, current); - if (ret) - goto out; - /* set the ptrace bit in the process flags. */ - current->ptrace |= PT_PTRACED; - goto out; + ret = ptrace_traceme(); + goto out; } - ret = -EPERM; - if (pid == 1) /* you may not mess with init */ + child = ptrace_get_task_struct(pid); + if (IS_ERR(child)) { + ret = PTR_ERR(child); goto out; + } - ret = -ESRCH; - read_lock(&tasklist_lock); - child = find_task_by_pid(pid); - if (child) - get_task_struct(child); - read_unlock(&tasklist_lock); - if (!child) - goto out; - if (!vx_check(vx_task_xid(child), VX_WATCH|VX_IDENT)) + if (!vx_check(vx_task_xid(child), VX_WATCH|VX_IDENT)) { + ret = -EPERM; goto out_tsk; + } ret = do_ptrace(child, request, addr, data); out_tsk: @@ -753,7 +740,7 @@ asmlinkage void syscall_trace(struct pt_regs *regs, int entryexit) { if (unlikely(current->audit_context) && entryexit) - audit_syscall_exit(current, AUDITSC_RESULT(regs->gprs[2]), regs->gprs[2]); + audit_syscall_exit(AUDITSC_RESULT(regs->gprs[2]), regs->gprs[2]); if (!test_thread_flag(TIF_SYSCALL_TRACE)) goto out; @@ -780,8 +767,7 @@ syscall_trace(struct pt_regs *regs, int entryexit) } out: if (unlikely(current->audit_context) && !entryexit) - audit_syscall_entry(current, - test_thread_flag(TIF_31BIT)?AUDIT_ARCH_S390:AUDIT_ARCH_S390X, + 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]); }