[PATCH 2/2] use ptrace_get_task_struct in all ptrace implementations

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



As part of my previous sys_ptrace consolidation I introduce a
ptrace_get_task_struct helper, that gets a reference to the taskstruct
for a given pid, after doing all the ptrace attach checks.
This pathces makes all but a few ptrace and compat_ptrace
implementations use it.  The implementations not covered are:

  - m68k: has some large ptrace changes pending, should be converted to
    the common sys_ptrace later
  - ia64 (native ptrace only): does some wierd stuff about finding a
    different thread in the same threadgroup


Signed-off-by: Christoph Hellwig <[email protected]>

Index: linux-2.6/arch/alpha/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/alpha/kernel/ptrace.c	2005-08-13 18:13:26.000000000 +0200
+++ linux-2.6/arch/alpha/kernel/ptrace.c	2005-08-13 18:14:22.000000000 +0200
@@ -265,28 +265,7 @@
 	lock_kernel();
 	DBG(DBG_MEM, ("request=%ld pid=%ld addr=0x%lx data=0x%lx\n",
 		      request, pid, addr, data));
-	ret = -EPERM;
-	if (request == PTRACE_TRACEME) {
-		/* are we already being traced? */
-		if (current->ptrace & PT_PTRACED)
-			goto out_notsk;
-		ret = security_ptrace(current->parent, current);
-		if (ret)
-			goto out_notsk;
-		/* set the ptrace bit in the process ptrace flags. */
-		current->ptrace |= PT_PTRACED;
-		ret = 0;
-		goto out_notsk;
-	}
-	if (pid == 1)		/* you may not mess with init */
-		goto out_notsk;
-
-	ret = -ESRCH;
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
+	ret = ptrace_get_task_struct(request, pid, &child);
 	if (!child)
 		goto out_notsk;
 
Index: linux-2.6/arch/ia64/ia32/sys_ia32.c
===================================================================
--- linux-2.6.orig/arch/ia64/ia32/sys_ia32.c	2005-08-13 18:13:26.000000000 +0200
+++ linux-2.6/arch/ia64/ia32/sys_ia32.c	2005-08-13 18:14:22.000000000 +0200
@@ -1759,22 +1759,9 @@
 	long i, ret;
 
 	lock_kernel();
-	if (request == PTRACE_TRACEME) {
-		ret = sys_ptrace(request, pid, addr, data);
-		goto out;
-	}
-
-	ret = -ESRCH;
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
+	ret = ptrace_get_task_struct(request, pid, &child);
 	if (!child)
 		goto out;
-	ret = -EPERM;
-	if (pid == 1)		/* no messing around with init! */
-		goto out_tsk;
 
 	if (request == PTRACE_ATTACH) {
 		ret = sys_ptrace(request, pid, addr, data);
Index: linux-2.6/arch/m32r/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/m32r/kernel/ptrace.c	2005-08-13 18:13:26.000000000 +0200
+++ linux-2.6/arch/m32r/kernel/ptrace.c	2005-08-13 18:14:22.000000000 +0200
@@ -762,29 +762,10 @@
 	int ret;
 
 	lock_kernel();
-	ret = -EPERM;
-	if (request == PTRACE_TRACEME) {
-		/* are we already being traced? */
-		if (current->ptrace & PT_PTRACED)
-			goto out;
-		/* set the ptrace bit in the process flags. */
-		current->ptrace |= PT_PTRACED;
-		ret = 0;
-		goto out;
-	}
-	ret = -ESRCH;
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
+	ret = ptrace_get_task_struct(request, pid, &child);
 	if (!child)
 		goto out;
 
-	ret = -EPERM;
-	if (pid == 1)		/* you may not mess with init */
-		goto out;
-
 	if (request == PTRACE_ATTACH) {
 		ret = ptrace_attach(child);
 		if (ret == 0)
Index: linux-2.6/arch/mips/kernel/ptrace32.c
===================================================================
--- linux-2.6.orig/arch/mips/kernel/ptrace32.c	2005-08-13 18:13:26.000000000 +0200
+++ linux-2.6/arch/mips/kernel/ptrace32.c	2005-08-13 18:14:22.000000000 +0200
@@ -50,31 +50,10 @@
 	       (unsigned long) data);
 #endif
 	lock_kernel();
-	ret = -EPERM;
-	if (request == PTRACE_TRACEME) {
-		/* are we already being traced? */
-		if (current->ptrace & PT_PTRACED)
-			goto out;
-		if ((ret = security_ptrace(current->parent, current)))
-			goto out;
-		/* set the ptrace bit in the process flags. */
-		current->ptrace |= PT_PTRACED;
-		ret = 0;
-		goto out;
-	}
-	ret = -ESRCH;
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
+	ret = ptrace_get_task_struct(request, pid, &child);
 	if (!child)
 		goto out;
 
-	ret = -EPERM;
-	if (pid == 1)		/* you may not mess with init */
-		goto out_tsk;
-
 	if (request == PTRACE_ATTACH) {
 		ret = ptrace_attach(child);
 		goto out_tsk;
Index: linux-2.6/arch/parisc/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/parisc/kernel/ptrace.c	2005-08-13 18:13:26.000000000 +0200
+++ linux-2.6/arch/parisc/kernel/ptrace.c	2005-08-13 18:14:22.000000000 +0200
@@ -87,33 +87,9 @@
 #endif
 
 	lock_kernel();
-	ret = -EPERM;
-	if (request == PTRACE_TRACEME) {
-		/* are we already being traced? */
-		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;
-		ret = 0;
-		goto out;
-	}
-
-	ret = -ESRCH;
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
+	ret = ptrace_get_task_struct(request, pid, &child);
 	if (!child)
 		goto out;
-	ret = -EPERM;
-	if (pid == 1)		/* no messing around with init! */
-		goto out_tsk;
 
 	if (request == PTRACE_ATTACH) {
 		ret = ptrace_attach(child);
Index: linux-2.6/arch/ppc64/kernel/ptrace32.c
===================================================================
--- linux-2.6.orig/arch/ppc64/kernel/ptrace32.c	2005-08-13 18:13:26.000000000 +0200
+++ linux-2.6/arch/ppc64/kernel/ptrace32.c	2005-08-13 18:14:22.000000000 +0200
@@ -45,31 +45,10 @@
 	int ret = -EPERM;
 
 	lock_kernel();
-	if (request == PTRACE_TRACEME) {
-		/* are we already being traced? */
-		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;
-		ret = 0;
-		goto out;
-	}
-	ret = -ESRCH;
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
+	ret = ptrace_get_task_struct(request, pid, &child);
 	if (!child)
 		goto out;
 
-	ret = -EPERM;
-	if (pid == 1)		/* you may not mess with init */
-		goto out_tsk;
-
 	if (request == PTRACE_ATTACH) {
 		ret = ptrace_attach(child);
 		goto out_tsk;
Index: linux-2.6/arch/s390/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/s390/kernel/ptrace.c	2005-08-13 18:13:26.000000000 +0200
+++ linux-2.6/arch/s390/kernel/ptrace.c	2005-08-13 18:14:22.000000000 +0200
@@ -712,36 +712,11 @@
 	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_get_task_struct(request, pid, &child);
+	if (child) {
+		ret = do_ptrace(child, request, addr, data);
+		put_task_struct(child);
 	}
-
-	ret = -EPERM;
-	if (pid == 1)		/* you may not mess with init */
-		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;
-
-	ret = do_ptrace(child, request, addr, data);
-
-	put_task_struct(child);
 out:
 	unlock_kernel();
 	return ret;
Index: linux-2.6/arch/sparc/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/sparc/kernel/ptrace.c	2005-08-13 18:13:26.000000000 +0200
+++ linux-2.6/arch/sparc/kernel/ptrace.c	2005-08-13 18:14:22.000000000 +0200
@@ -286,40 +286,13 @@
 			       s, (int) request, (int) pid, addr, data, addr2);
 	}
 #endif
-	if (request == PTRACE_TRACEME) {
-		int my_ret;
-
-		/* are we already being traced? */
-		if (current->ptrace & PT_PTRACED) {
-			pt_error_return(regs, EPERM);
-			goto out;
-		}
-		my_ret = security_ptrace(current->parent, current);
-		if (my_ret) {
-			pt_error_return(regs, -my_ret);
-			goto out;
-		}
-
-		/* set the ptrace bit in the process flags. */
-		current->ptrace |= PT_PTRACED;
-		pt_succ_return(regs, 0);
-		goto out;
-	}
-#ifndef ALLOW_INIT_TRACING
-	if (pid == 1) {
-		/* Can't dork with init. */
-		pt_error_return(regs, EPERM);
-		goto out;
-	}
-#endif
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
 
+	ret = ptrace_get_task_struct(request, pid, &child);
 	if (!child) {
-		pt_error_return(regs, ESRCH);
+		if (ret)
+			pt_error_return(regs, -ret);
+		else
+			pt_succ_return(regs, 0);
 		goto out;
 	}
 
Index: linux-2.6/arch/sparc64/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/arch/sparc64/kernel/ptrace.c	2005-08-13 18:13:26.000000000 +0200
+++ linux-2.6/arch/sparc64/kernel/ptrace.c	2005-08-13 18:14:22.000000000 +0200
@@ -188,40 +188,12 @@
 			       s, request, pid, addr, data, addr2);
 	}
 #endif
-	if (request == PTRACE_TRACEME) {
-		int ret;
-
-		/* are we already being traced? */
-		if (current->ptrace & PT_PTRACED) {
-			pt_error_return(regs, EPERM);
-			goto out;
-		}
-		ret = security_ptrace(current->parent, current);
-		if (ret) {
-			pt_error_return(regs, -ret);
-			goto out;
-		}
-
-		/* set the ptrace bit in the process flags. */
-		current->ptrace |= PT_PTRACED;
-		pt_succ_return(regs, 0);
-		goto out;
-	}
-#ifndef ALLOW_INIT_TRACING
-	if (pid == 1) {
-		/* Can't dork with init. */
-		pt_error_return(regs, EPERM);
-		goto out;
-	}
-#endif
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
-
+	ret = ptrace_get_task_struct(request, pid, &child);
 	if (!child) {
-		pt_error_return(regs, ESRCH);
+		if (ret)
+			pt_error_return(regs, -ret);
+		else
+			pt_succ_return(regs, 0);
 		goto out;
 	}
 
Index: linux-2.6/arch/x86_64/ia32/ptrace32.c
===================================================================
--- linux-2.6.orig/arch/x86_64/ia32/ptrace32.c	2005-08-13 18:13:26.000000000 +0200
+++ linux-2.6/arch/x86_64/ia32/ptrace32.c	2005-08-13 18:14:22.000000000 +0200
@@ -196,36 +196,6 @@
 
 #undef R32
 
-static struct task_struct *find_target(int request, int pid, int *err)
-{ 
-	struct task_struct *child;
-
-	*err = -EPERM; 
-	if (pid == 1)
-		return NULL; 
-
-	*err = -ESRCH;
-	read_lock(&tasklist_lock);
-	child = find_task_by_pid(pid);
-	if (child)
-		get_task_struct(child);
-	read_unlock(&tasklist_lock);
-	if (child) { 
-		*err = -EPERM;
-		if (child->pid == 1) 
-			goto out;
-		*err = ptrace_check_attach(child, request == PTRACE_KILL); 
-		if (*err < 0) 
-			goto out;
-		return child; 
-	} 
- out:
-	if (child)
-	put_task_struct(child);
-	return NULL; 
-	
-} 
-
 asmlinkage long sys32_ptrace(long request, u32 pid, u32 addr, u32 data)
 {
 	struct task_struct *child;
@@ -254,10 +224,14 @@
 		break;
 	} 
 
-	child = find_target(request, pid, &ret);
+	ret = ptrace_get_task_struct(request, pid, &child);
 	if (!child)
 		return ret;
 
+	ret = ptrace_check_attach(child, request == PTRACE_KILL);
+	if (ret < 0)
+		goto out;
+
 	childregs = (struct pt_regs *)(child->thread.rsp0 - sizeof(struct pt_regs)); 
 
 	switch (request) {
@@ -373,6 +347,7 @@
 		break;
 	}
 
+ out:
 	put_task_struct(child);
 	return ret;
 }
Index: linux-2.6/kernel/ptrace.c
===================================================================
--- linux-2.6.orig/kernel/ptrace.c	2005-08-13 18:14:17.000000000 +0200
+++ linux-2.6/kernel/ptrace.c	2005-08-13 18:14:22.000000000 +0200
@@ -389,9 +389,7 @@
 	return ret;
 }
 
-#ifndef __ARCH_SYS_PTRACE
-static int ptrace_get_task_struct(long request, long pid,
-		struct task_struct **childp)
+int ptrace_get_task_struct(long request, long pid, struct task_struct **childp)
 {
 	struct task_struct *child;
 	int ret;
@@ -437,6 +435,7 @@
 	return 0;
 }
 
+#ifndef __ARCH_SYS_PTRACE
 asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
 {
 	struct task_struct *child;
Index: linux-2.6/include/linux/ptrace.h
===================================================================
--- linux-2.6.orig/include/linux/ptrace.h	2005-08-13 18:13:26.000000000 +0200
+++ linux-2.6/include/linux/ptrace.h	2005-08-13 18:14:22.000000000 +0200
@@ -78,6 +78,7 @@
 
 
 extern long arch_ptrace(struct task_struct *child, long request, long addr, long data);
+extern int ptrace_get_task_struct(long request, long pid, struct task_struct **childp);
 extern int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len);
 extern int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int len);
 extern int ptrace_attach(struct task_struct *tsk);
-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]
  Powered by Linux