From 7413429e76970db29125812e0b7fe504e8904807 Mon Sep 17 00:00:00 2001 From: Roland McGrath Date: Wed, 30 Jan 2008 13:31:48 +0100 Subject: [PATCH] --- yaml --- r: 80061 b: refs/heads/master c: c269f19617f508cc5c29c0b064c1a437d7011a46 h: refs/heads/master i: 80059: 656874419b73e120262cb763b9139e2945f6b5c9 v: v3 --- [refs] | 2 +- trunk/include/linux/compat.h | 7 ++++++ trunk/kernel/ptrace.c | 46 ++++++++++++++++++++++++++++++++++++ 3 files changed, 54 insertions(+), 1 deletion(-) diff --git a/[refs] b/[refs] index 2d5cedbcb9f0..559b7aef5f9c 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 032d82d9065dec0e26718eca376c2029e4bd0595 +refs/heads/master: c269f19617f508cc5c29c0b064c1a437d7011a46 diff --git a/trunk/include/linux/compat.h b/trunk/include/linux/compat.h index a907fbede6c3..d38655f2be70 100644 --- a/trunk/include/linux/compat.h +++ b/trunk/include/linux/compat.h @@ -247,6 +247,13 @@ extern int compat_ptrace_request(struct task_struct *child, compat_long_t request, 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 ... */ diff --git a/trunk/kernel/ptrace.c b/trunk/kernel/ptrace.c index ed1c3d56c2cd..e6e9b8be4b05 100644 --- a/trunk/kernel/ptrace.c +++ b/trunk/kernel/ptrace.c @@ -644,4 +644,50 @@ int compat_ptrace_request(struct task_struct *child, compat_long_t request, 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 */