x86: compat_sys_ptrace
This adds a generic definition of compat_sys_ptrace that calls compat_arch_ptrace, parallel to sys_ptrace/arch_ptrace. Some machines needing this already define a function by that name. The new generic function is defined only on machines that put #define __ARCH_WANT_COMPAT_SYS_PTRACE into asm/ptrace.h. Signed-off-by: Roland McGrath <roland@redhat.com> Signed-off-by: Ingo Molnar <mingo@elte.hu> Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
parent
032d82d906
commit
c269f19617
|
@ -247,6 +247,13 @@ extern int compat_ptrace_request(struct task_struct *child,
|
||||||
compat_long_t request,
|
compat_long_t request,
|
||||||
compat_ulong_t addr, compat_ulong_t data);
|
compat_ulong_t addr, compat_ulong_t data);
|
||||||
|
|
||||||
|
#ifdef __ARCH_WANT_COMPAT_SYS_PTRACE
|
||||||
|
extern long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
|
||||||
|
compat_ulong_t addr, compat_ulong_t data);
|
||||||
|
asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid,
|
||||||
|
compat_long_t addr, compat_long_t data);
|
||||||
|
#endif /* __ARCH_WANT_COMPAT_SYS_PTRACE */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* epoll (fs/eventpoll.c) compat bits follow ...
|
* epoll (fs/eventpoll.c) compat bits follow ...
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -644,4 +644,50 @@ int compat_ptrace_request(struct task_struct *child, compat_long_t request,
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef __ARCH_WANT_COMPAT_SYS_PTRACE
|
||||||
|
asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid,
|
||||||
|
compat_long_t addr, compat_long_t data)
|
||||||
|
{
|
||||||
|
struct task_struct *child;
|
||||||
|
long ret;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This lock_kernel fixes a subtle race with suid exec
|
||||||
|
*/
|
||||||
|
lock_kernel();
|
||||||
|
if (request == PTRACE_TRACEME) {
|
||||||
|
ret = ptrace_traceme();
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
child = ptrace_get_task_struct(pid);
|
||||||
|
if (IS_ERR(child)) {
|
||||||
|
ret = PTR_ERR(child);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (request == PTRACE_ATTACH) {
|
||||||
|
ret = ptrace_attach(child);
|
||||||
|
/*
|
||||||
|
* Some architectures need to do book-keeping after
|
||||||
|
* a ptrace attach.
|
||||||
|
*/
|
||||||
|
if (!ret)
|
||||||
|
arch_ptrace_attach(child);
|
||||||
|
goto out_put_task_struct;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = ptrace_check_attach(child, request == PTRACE_KILL);
|
||||||
|
if (!ret)
|
||||||
|
ret = compat_arch_ptrace(child, request, addr, data);
|
||||||
|
|
||||||
|
out_put_task_struct:
|
||||||
|
put_task_struct(child);
|
||||||
|
out:
|
||||||
|
unlock_kernel();
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif /* __ARCH_WANT_COMPAT_SYS_PTRACE */
|
||||||
|
|
||||||
#endif /* CONFIG_COMPAT */
|
#endif /* CONFIG_COMPAT */
|
||||||
|
|
Loading…
Reference in New Issue