rpms/kernel/devel kernel.spec, 1.2001, 1.2002 linux-2.6-utrace-ptrace.patch, 1.4, 1.5

roland roland at fedoraproject.org
Sat May 22 00:53:20 UTC 2010


Author: roland

Update of /cvs/pkgs/rpms/kernel/devel
In directory cvs01.phx2.fedoraproject.org:/tmp/cvs-serv19389

Modified Files:
	kernel.spec linux-2.6-utrace-ptrace.patch 
Log Message:
this time, with feeling


Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/kernel.spec,v
retrieving revision 1.2001
retrieving revision 1.2002
diff -u -p -r1.2001 -r1.2002
--- kernel.spec	21 May 2010 22:43:56 -0000	1.2001
+++ kernel.spec	22 May 2010 00:53:19 -0000	1.2002
@@ -2034,7 +2034,7 @@ fi
 #                 ||     ||
 
 %changelog
-* Fri May 21 2010 Roland McGrath <roland at redhat.com> 2.6.34-10
+* Fri May 21 2010 Roland McGrath <roland at redhat.com> 2.6.34-11
 - utrace update
 
 * Fri May 21 2010 Dave Jones <davej at redhat.com>

linux-2.6-utrace-ptrace.patch:
 include/linux/ptrace.h |    2 
 kernel/Makefile        |    1 
 kernel/ptrace-utrace.c | 1127 +++++++++++++++++++++++++++++++++++++++++++++++++
 kernel/ptrace.c        |  695 ++++++++++++++----------------
 kernel/utrace.c        |   16 
 5 files changed, 1487 insertions(+), 354 deletions(-)

Index: linux-2.6-utrace-ptrace.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/linux-2.6-utrace-ptrace.patch,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -p -r1.4 -r1.5
--- linux-2.6-utrace-ptrace.patch	21 May 2010 22:43:56 -0000	1.4
+++ linux-2.6-utrace-ptrace.patch	22 May 2010 00:53:20 -0000	1.5
@@ -15,9 +15,9 @@ Signed-off-by: Oleg Nesterov <oleg at redha
  include/linux/ptrace.h |    2 +-
  kernel/Makefile        |    1 +
  kernel/ptrace-utrace.c | 1127 ++++++++++++++++++++++++++++++++++++++++++++++++
- kernel/ptrace.c        |  576 ++++++++++++-------------
+ kernel/ptrace.c        |  654 ++++++++++++++--------------
  kernel/utrace.c        |   16 +
- 5 files changed, 1427 insertions(+), 295 deletions(-)
+ 5 files changed, 1466 insertions(+), 334 deletions(-)
 
 diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h
 index 0d84f1e..102cb0f 100644  
@@ -1178,7 +1178,7 @@ index ...86234ee 100644  
 +}
 +#endif	/* CONFIG_COMPAT */
 diff --git a/kernel/ptrace.c b/kernel/ptrace.c
-index 0ad4dc0..deae114 100644  
+index 0ad4dc0..448b353 100644  
 --- a/kernel/ptrace.c
 +++ b/kernel/ptrace.c
 @@ -16,7 +16,6 @@
@@ -1189,7 +1189,7 @@ index 0ad4dc0..deae114 100644  
  #include <linux/security.h>
  #include <linux/signal.h>
  #include <linux/audit.h>
-@@ -25,7 +24,286 @@
+@@ -25,7 +24,327 @@
  #include <linux/uaccess.h>
  #include <linux/regset.h>
  
@@ -1341,6 +1341,47 @@ index 0ad4dc0..deae114 100644  
 +	return copied;
 +}
 +
++#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
++
++static const struct user_regset *
++find_regset(const struct user_regset_view *view, unsigned int type)
++{
++	const struct user_regset *regset;
++	int n;
++
++	for (n = 0; n < view->n; ++n) {
++		regset = view->regsets + n;
++		if (regset->core_note_type == type)
++			return regset;
++	}
++
++	return NULL;
++}
++
++int ptrace_regset(struct task_struct *task, int req, unsigned int type,
++		  struct iovec *kiov)
++{
++	const struct user_regset_view *view = task_user_regset_view(task);
++	const struct user_regset *regset = find_regset(view, type);
++	int regset_no;
++
++	if (!regset || (kiov->iov_len % regset->size) != 0)
++		return -EINVAL;
++
++	regset_no = regset - view->regsets;
++	kiov->iov_len = min(kiov->iov_len,
++			    (__kernel_size_t) (regset->n * regset->size));
++
++	if (req == PTRACE_GETREGSET)
++		return copy_regset_to_user(task, view, regset_no, 0,
++					   kiov->iov_len, kiov->iov_base);
++	else
++		return copy_regset_from_user(task, view, regset_no, 0,
++					     kiov->iov_len, kiov->iov_base);
++}
++
++#endif
++
 +static struct task_struct *ptrace_get_task_struct(pid_t pid)
 +{
 +	struct task_struct *child;
@@ -1359,7 +1400,7 @@ index 0ad4dc0..deae114 100644  
 +#ifndef arch_ptrace_attach
 +#define arch_ptrace_attach(child)	do { } while (0)
 +#endif
- 
++
 +SYSCALL_DEFINE4(ptrace, long, request, long, pid, long, addr, long, data)
 +{
 +	struct task_struct *child;
@@ -1405,7 +1446,7 @@ index 0ad4dc0..deae114 100644  
 +	unlock_kernel();
 +	return ret;
 +}
-+
+ 
 +int generic_ptrace_peekdata(struct task_struct *tsk, long addr, long data)
 +{
 +	unsigned long tmp;
@@ -1476,27 +1517,10 @@ index 0ad4dc0..deae114 100644  
  /*
   * ptrace a task: make the debugger its new parent and
   * move it to the ptrace list.
-@@ -102,76 +380,21 @@ int ptrace_check_attach(struct task_stru
- 		/*
- 		 * child->sighand can't be NULL, release_task()
- 		 * does ptrace_unlink() before __exit_signal().
--		 */
--		spin_lock_irq(&child->sighand->siglock);
--		if (task_is_stopped(child))
--			child->state = TASK_TRACED;
--		else if (!task_is_traced(child) && !kill)
--			ret = -ESRCH;
--		spin_unlock_irq(&child->sighand->siglock);
--	}
--	read_unlock(&tasklist_lock);
--
--	if (!ret && !kill)
--		ret = wait_task_inactive(child, TASK_TRACED) ? 0 : -ESRCH;
--
--	/* All systems go.. */
--	return ret;
--}
--
+@@ -119,61 +438,6 @@ int ptrace_check_attach(struct task_stru
+ 	return ret;
+ }
+ 
 -int __ptrace_may_access(struct task_struct *task, unsigned int mode)
 -{
 -	const struct cred *cred = current_cred(), *tcred;
@@ -1534,16 +1558,7 @@ index 0ad4dc0..deae114 100644  
 -
 -	return security_ptrace_access_check(task, mode);
 -}
-+		 */
-+		spin_lock_irq(&child->sighand->siglock);
-+		if (task_is_stopped(child))
-+			child->state = TASK_TRACED;
-+		else if (!task_is_traced(child) && !kill)
-+			ret = -ESRCH;
-+		spin_unlock_irq(&child->sighand->siglock);
-+	}
-+	read_unlock(&tasklist_lock);
- 
+-
 -bool ptrace_may_access(struct task_struct *task, unsigned int mode)
 -{
 -	int err;
@@ -1552,21 +1567,19 @@ index 0ad4dc0..deae114 100644  
 -	task_unlock(task);
 -	return !err;
 -}
-+	if (!ret && !kill)
-+		ret = wait_task_inactive(child, TASK_TRACED) ? 0 : -ESRCH;
- 
+-
 -/*
 - * For experimental use of utrace, exclude ptrace on the same task.
 - */
 -static inline bool exclude_ptrace(struct task_struct *task)
 -{
 -	return unlikely(!!task_utrace_flags(task));
-+	/* All systems go.. */
-+	return ret;
- }
- 
+-}
+-
  int ptrace_attach(struct task_struct *task)
-@@ -197,8 +420,6 @@ int ptrace_attach(struct task_struct *ta
+ {
+ 	int retval;
+@@ -197,8 +461,6 @@ int ptrace_attach(struct task_struct *ta
  
  	task_lock(task);
  	retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH);
@@ -1575,20 +1588,42 @@ index 0ad4dc0..deae114 100644  
  	task_unlock(task);
  	if (retval)
  		goto unlock_creds;
-@@ -236,9 +457,6 @@ int ptrace_traceme(void)
- {
- 	int ret = -EPERM;
+@@ -226,87 +488,33 @@ out:
+ 	return retval;
+ }
  
+-/**
+- * ptrace_traceme  --  helper for PTRACE_TRACEME
+- *
+- * Performs checks and sets PT_PTRACED.
+- * Should be used by all ptrace implementations for PTRACE_TRACEME.
+- */
+-int ptrace_traceme(void)
+-{
+-	int ret = -EPERM;
+-
 -	if (exclude_ptrace(current)) /* XXX locking */
 -		return -EBUSY;
 -
- 	write_lock_irq(&tasklist_lock);
- 	/* Are we already being traced? */
- 	if (!current->ptrace) {
-@@ -258,57 +476,6 @@ int ptrace_traceme(void)
- 	return ret;
- }
- 
+-	write_lock_irq(&tasklist_lock);
+-	/* Are we already being traced? */
+-	if (!current->ptrace) {
+-		ret = security_ptrace_traceme(current->parent);
+-		/*
+-		 * Check PF_EXITING to ensure ->real_parent has not passed
+-		 * exit_ptrace(). Otherwise we don't report the error but
+-		 * pretend ->real_parent untraces us right after return.
+-		 */
+-		if (!ret && !(current->real_parent->flags & PF_EXITING)) {
+-			current->ptrace = PT_PTRACED;
+-			__ptrace_link(current, current->real_parent);
+-		}
+-	}
+-	write_unlock_irq(&tasklist_lock);
+-
+-	return ret;
+-}
+-
 -/*
 - * Called with irqs disabled, returns true if childs should reap themselves.
 - */
@@ -1616,11 +1651,18 @@ index 0ad4dc0..deae114 100644  
 - * children self-reap, then this child was prevented by ptrace and we must
 - * reap it now, in that case we must also wake up sub-threads sleeping in
 - * do_wait().
-- */
++/**
++ * ptrace_traceme  --  helper for PTRACE_TRACEME
++ *
++ * Performs checks and sets PT_PTRACED.
++ * Should be used by all ptrace implementations for PTRACE_TRACEME.
+  */
 -bool __ptrace_detach(struct task_struct *tracer, struct task_struct *p)
--{
++int ptrace_traceme(void)
+ {
 -	__ptrace_unlink(p);
--
++	int ret = -EPERM;
+ 
 -	if (p->exit_state == EXIT_ZOMBIE) {
 -		if (!task_detached(p) && thread_group_empty(p)) {
 -			if (!same_thread_group(p->real_parent, tracer))
@@ -1634,16 +1676,28 @@ index 0ad4dc0..deae114 100644  
 -			/* Mark it as in the process of being reaped. */
 -			p->exit_state = EXIT_DEAD;
 -			return true;
--		}
--	}
--
++	write_lock_irq(&tasklist_lock);
++	/* Are we already being traced? */
++	if (!current->ptrace) {
++		ret = security_ptrace_traceme(current->parent);
++		/*
++		 * Check PF_EXITING to ensure ->real_parent has not passed
++		 * exit_ptrace(). Otherwise we don't report the error but
++		 * pretend ->real_parent untraces us right after return.
++		 */
++		if (!ret && !(current->real_parent->flags & PF_EXITING)) {
++			current->ptrace = PT_PTRACED;
++			__ptrace_link(current, current->real_parent);
+ 		}
+ 	}
++	write_unlock_irq(&tasklist_lock);
+ 
 -	return false;
--}
--
++	return ret;
+ }
+ 
  int ptrace_detach(struct task_struct *child, unsigned int data)
- {
- 	bool dead = false;
-@@ -362,56 +529,6 @@ void exit_ptrace(struct task_struct *tra
+@@ -362,56 +570,6 @@ void exit_ptrace(struct task_struct *tra
  	}
  }
  
@@ -1700,17 +1754,54 @@ index 0ad4dc0..deae114 100644  
  static int ptrace_setoptions(struct task_struct *child, long data)
  {
  	child->ptrace &= ~PT_TRACE_MASK;
-@@ -543,8 +659,8 @@ find_regset(const struct user_regset_vie
- 	return NULL;
+@@ -526,47 +683,6 @@ static int ptrace_resume(struct task_str
+ 	return 0;
  }
  
+-#ifdef CONFIG_HAVE_ARCH_TRACEHOOK
+-
+-static const struct user_regset *
+-find_regset(const struct user_regset_view *view, unsigned int type)
+-{
+-	const struct user_regset *regset;
+-	int n;
+-
+-	for (n = 0; n < view->n; ++n) {
+-		regset = view->regsets + n;
+-		if (regset->core_note_type == type)
+-			return regset;
+-	}
+-
+-	return NULL;
+-}
+-
 -static int ptrace_regset(struct task_struct *task, int req, unsigned int type,
 -			 struct iovec *kiov)
-+int ptrace_regset(struct task_struct *task, int req, unsigned int type,
-+		  struct iovec *kiov)
+-{
+-	const struct user_regset_view *view = task_user_regset_view(task);
+-	const struct user_regset *regset = find_regset(view, type);
+-	int regset_no;
+-
+-	if (!regset || (kiov->iov_len % regset->size) != 0)
+-		return -EINVAL;
+-
+-	regset_no = regset - view->regsets;
+-	kiov->iov_len = min(kiov->iov_len,
+-			    (__kernel_size_t) (regset->n * regset->size));
+-
+-	if (req == PTRACE_GETREGSET)
+-		return copy_regset_to_user(task, view, regset_no, 0,
+-					   kiov->iov_len, kiov->iov_base);
+-	else
+-		return copy_regset_from_user(task, view, regset_no, 0,
+-					     kiov->iov_len, kiov->iov_base);
+-}
+-
+-#endif
+-
+ int ptrace_request(struct task_struct *child, long request,
+ 		   long addr, long data)
  {
- 	const struct user_regset_view *view = task_user_regset_view(task);
- 	const struct user_regset *regset = find_regset(view, type);
 @@ -656,93 +772,7 @@ int ptrace_request(struct task_struct *c
  	return ret;
  }



More information about the scm-commits mailing list