From: Miklos Szeredi <[email-masked]>

Extract common code used by ptrace_attach() and may_ptrace_attach()
into a separate function.

Signed-off-by: Miklos Szeredi <[email-masked]>
Cc: <[email-masked]>
Cc: Christoph Hellwig <[email-masked]>
Signed-off-by: Andrew Morton <[email-masked]>
---

 fs/proc/base.c         |   35 ++++-------------------------------
 include/linux/ptrace.h |    1 +
 kernel/ptrace.c        |   41 ++++++++++++++++++++++++++++-------------
 3 files changed, 33 insertions(+), 44 deletions(-)

diff -puN fs/proc/base.c~remove-duplicated-code-from-proc-and-ptrace fs/proc/base.c
--- devel/fs/proc/base.c~remove-duplicated-code-from-proc-and-ptrace	2005-08-30 18:42:03.000000000 -0700
+++ devel-akpm/fs/proc/base.c	2005-08-30 18:42:03.000000000 -0700
@@ -346,33 +346,6 @@ static int proc_root_link(struct inode *
 	 (task->state == TASK_STOPPED || task->state == TASK_TRACED) && \
 	 security_ptrace(current,task) == 0))
 
-static int may_ptrace_attach(struct task_struct *task)
-{
-	int retval = 0;
-
-	task_lock(task);
-
-	if (!task->mm)
-		goto out;
-	if (((current->uid != task->euid) ||
-	     (current->uid != task->suid) ||
-	     (current->uid != task->uid) ||
-	     (current->gid != task->egid) ||
-	     (current->gid != task->sgid) ||
-	     (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
-		goto out;
-	rmb();
-	if (task->mm->dumpable != 1 && !capable(CAP_SYS_PTRACE))
-		goto out;
-	if (security_ptrace(current, task))
-		goto out;
-
-	retval = 1;
-out:
-	task_unlock(task);
-	return retval;
-}
-
 static int proc_pid_environ(struct task_struct *task, char * buffer)
 {
 	int res = 0;
@@ -382,7 +355,7 @@ static int proc_pid_environ(struct task_
 		if (len > PAGE_SIZE)
 			len = PAGE_SIZE;
 		res = access_process_vm(task, mm->env_start, buffer, len, 0);
-		if (!may_ptrace_attach(task))
+		if (!ptrace_may_attach(task))
 			res = -ESRCH;
 		mmput(mm);
 	}
@@ -685,7 +658,7 @@ static ssize_t mem_read(struct file * fi
 	int ret = -ESRCH;
 	struct mm_struct *mm;
 
-	if (!MAY_PTRACE(task) || !may_ptrace_attach(task))
+	if (!MAY_PTRACE(task) || !ptrace_may_attach(task))
 		goto out;
 
 	ret = -ENOMEM;
@@ -711,7 +684,7 @@ static ssize_t mem_read(struct file * fi
 
 		this_len = (count > PAGE_SIZE) ? PAGE_SIZE : count;
 		retval = access_process_vm(task, src, page, this_len, 0);
-		if (!retval || !MAY_PTRACE(task) || !may_ptrace_attach(task)) {
+		if (!retval || !MAY_PTRACE(task) || !ptrace_may_attach(task)) {
 			if (!ret)
 				ret = -EIO;
 			break;
@@ -749,7 +722,7 @@ static ssize_t mem_write(struct file * f
 	struct task_struct *task = proc_task(file->f_dentry->d_inode);
 	unsigned long dst = *ppos;
 
-	if (!MAY_PTRACE(task) || !may_ptrace_attach(task))
+	if (!MAY_PTRACE(task) || !ptrace_may_attach(task))
 		return -ESRCH;
 
 	page = (char *)__get_free_page(GFP_USER);
diff -puN include/linux/ptrace.h~remove-duplicated-code-from-proc-and-ptrace include/linux/ptrace.h
--- devel/include/linux/ptrace.h~remove-duplicated-code-from-proc-and-ptrace	2005-08-30 18:42:03.000000000 -0700
+++ devel-akpm/include/linux/ptrace.h	2005-08-30 18:42:03.000000000 -0700
@@ -93,6 +93,7 @@ extern void __ptrace_link(struct task_st
 			  struct task_struct *new_parent);
 extern void __ptrace_unlink(struct task_struct *child);
 extern void ptrace_untrace(struct task_struct *child);
+extern int ptrace_may_attach(struct task_struct *task);
 
 static inline void ptrace_link(struct task_struct *child,
 			       struct task_struct *new_parent)
diff -puN kernel/ptrace.c~remove-duplicated-code-from-proc-and-ptrace kernel/ptrace.c
--- devel/kernel/ptrace.c~remove-duplicated-code-from-proc-and-ptrace	2005-08-30 18:42:03.000000000 -0700
+++ devel-akpm/kernel/ptrace.c	2005-08-30 18:42:03.000000000 -0700
@@ -118,6 +118,33 @@ int ptrace_check_attach(struct task_stru
 	return ret;
 }
 
+static int may_attach(struct task_struct *task)
+{
+	if (!task->mm)
+		return -EPERM;
+	if (((current->uid != task->euid) ||
+	     (current->uid != task->suid) ||
+	     (current->uid != task->uid) ||
+	     (current->gid != task->egid) ||
+	     (current->gid != task->sgid) ||
+	     (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
+		return -EPERM;
+	smp_rmb();
+	if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE))
+		return -EPERM;
+
+	return security_ptrace(current, task);
+}
+
+int ptrace_may_attach(struct task_struct *task)
+{
+	int err;
+	task_lock(task);
+	err = may_attach(task);
+	task_unlock(task);
+	return !err;
+}
+
 int ptrace_attach(struct task_struct *task)
 {
 	int retval;
@@ -127,22 +154,10 @@ int ptrace_attach(struct task_struct *ta
 		goto bad;
 	if (task == current)
 		goto bad;
-	if (!task->mm)
-		goto bad;
-	if(((current->uid != task->euid) ||
-	    (current->uid != task->suid) ||
-	    (current->uid != task->uid) ||
- 	    (current->gid != task->egid) ||
- 	    (current->gid != task->sgid) ||
- 	    (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
-		goto bad;
-	smp_rmb();
-	if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE))
-		goto bad;
 	/* the same process cannot be attached many times */
 	if (task->ptrace & PT_PTRACED)
 		goto bad;
-	retval = security_ptrace(current, task);
+	retval = may_attach(task);
 	if (retval)
 		goto bad;
 
_