rpms/kernel/devel kernel.spec, 1.994, 1.995 linux-2.6-utrace.patch, 1.100, 1.101

Roland McGrath roland at fedoraproject.org
Tue Sep 30 04:49:35 UTC 2008


Author: roland

Update of /cvs/pkgs/rpms/kernel/devel
In directory cvs1.fedora.phx.redhat.com:/tmp/cvs-serv10948

Modified Files:
	kernel.spec linux-2.6-utrace.patch 
Log Message:
- fix PTRACE_O_TRACEVFORK (#464520)


Index: kernel.spec
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/kernel.spec,v
retrieving revision 1.994
retrieving revision 1.995
diff -u -r1.994 -r1.995
--- kernel.spec	30 Sep 2008 03:54:35 -0000	1.994
+++ kernel.spec	30 Sep 2008 04:49:05 -0000	1.995
@@ -1741,7 +1741,9 @@
 %changelog
 * Mon Sep 29 2008 Roland McGrath <roland at redhat.com>
 - 2.6.27-rc8
-- utrace update: fix CLONE_PTRACE (#461552)
+- utrace update
+  - fix CLONE_PTRACE (#461552)
+  - fix PTRACE_O_TRACEVFORK (#464520)
 
 * Mon Sep 29 2008 Dave Jones <davej at redhat.com>
 - Turn off CONFIG_USB_DEBUG. It's noisy, and of no real value right now.

linux-2.6-utrace.patch:

Index: linux-2.6-utrace.patch
===================================================================
RCS file: /cvs/pkgs/rpms/kernel/devel/linux-2.6-utrace.patch,v
retrieving revision 1.100
retrieving revision 1.101
diff -u -r1.100 -r1.101
--- linux-2.6-utrace.patch	30 Sep 2008 03:54:35 -0000	1.100
+++ linux-2.6-utrace.patch	30 Sep 2008 04:49:05 -0000	1.101
@@ -1,16 +1,16 @@
  Documentation/DocBook/Makefile    |    2 +-
- Documentation/DocBook/utrace.tmpl |  566 +++++++++
+ Documentation/DocBook/utrace.tmpl |  566 ++++++++
  fs/proc/array.c                   |    3 +
  include/linux/ptrace.h            |   21 +
  include/linux/sched.h             |    6 +
- include/linux/tracehook.h         |   65 +-
- include/linux/utrace.h            |  705 ++++++++++
+ include/linux/tracehook.h         |   68 +-
+ include/linux/utrace.h            |  707 ++++++++++
  init/Kconfig                      |   26 +
  kernel/Makefile                   |    1 +
  kernel/ptrace.c                   |  609 +++++++++-
  kernel/signal.c                   |   14 +-
- kernel/utrace.c                   | 2538 +++++++++++++++++++++++++++++++++++++
- 12 files changed, 4548 insertions(+), 8 deletions(-)
+ kernel/utrace.c                   | 2570 +++++++++++++++++++++++++++++++++++++
+ 12 files changed, 4585 insertions(+), 8 deletions(-)
 
 diff --git a/Documentation/DocBook/Makefile b/Documentation/DocBook/Makefile
 index 1615350..92ca631 100644  
@@ -682,7 +682,7 @@
  extern void force_sig_specific(int, struct task_struct *);
  extern int send_sig(int, struct task_struct *, int);
 diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h
-index 6186a78..968909d 100644  
+index 6186a78..03a4555 100644  
 --- a/include/linux/tracehook.h
 +++ b/include/linux/tracehook.h
 @@ -49,6 +49,7 @@
@@ -777,7 +777,17 @@
  	if (unlikely(trace) || unlikely(clone_flags & CLONE_PTRACE)) {
  		/*
  		 * The child starts up with an immediate SIGSTOP.
-@@ -345,6 +366,9 @@ static inline void tracehook_report_vfor
+@@ -311,6 +332,9 @@ static inline void tracehook_report_clon
+ 						   pid_t pid,
+ 						   struct task_struct *child)
+ {
++	if (unlikely(task_utrace_flags(current) & UTRACE_EVENT(CLONE)) &&
++	    (clone_flags & CLONE_VFORK))
++		utrace_finish_vfork(current);
+ 	if (unlikely(trace))
+ 		ptrace_event(0, trace, pid);
+ }
+@@ -345,6 +369,9 @@ static inline void tracehook_report_vfor
   */
  static inline void tracehook_prepare_release_task(struct task_struct *task)
  {
@@ -787,7 +797,7 @@
  }
  
  /**
-@@ -358,7 +382,21 @@ static inline void tracehook_prepare_rel
+@@ -358,7 +385,21 @@ static inline void tracehook_prepare_rel
   */
  static inline void tracehook_finish_release_task(struct task_struct *task)
  {
@@ -809,7 +819,7 @@
  }
  
  /**
-@@ -380,8 +418,12 @@ static inline void tracehook_signal_hand
+@@ -380,8 +421,12 @@ static inline void tracehook_signal_hand
  					    const struct k_sigaction *ka,
  					    struct pt_regs *regs, int stepping)
  {
@@ -822,7 +832,7 @@
  }
  
  /**
-@@ -400,6 +442,8 @@ static inline int tracehook_consider_ign
+@@ -400,6 +445,8 @@ static inline int tracehook_consider_ign
  						    int sig,
  						    void __user *handler)
  {
@@ -831,7 +841,7 @@
  	return (task_ptrace(task) & PT_PTRACED) != 0;
  }
  
-@@ -421,6 +465,9 @@ static inline int tracehook_consider_fat
+@@ -421,6 +468,9 @@ static inline int tracehook_consider_fat
  						  int sig,
  						  void __user *handler)
  {
@@ -841,7 +851,7 @@
  	return (task_ptrace(task) & PT_PTRACED) != 0;
  }
  
-@@ -435,6 +482,8 @@ static inline int tracehook_consider_fat
+@@ -435,6 +485,8 @@ static inline int tracehook_consider_fat
   */
  static inline int tracehook_force_sigpending(void)
  {
@@ -850,7 +860,7 @@
  	return 0;
  }
  
-@@ -464,6 +513,8 @@ static inline int tracehook_get_signal(s
+@@ -464,6 +516,8 @@ static inline int tracehook_get_signal(s
  				       siginfo_t *info,
  				       struct k_sigaction *return_ka)
  {
@@ -859,7 +869,7 @@
  	return 0;
  }
  
-@@ -484,6 +535,8 @@ static inline int tracehook_get_signal(s
+@@ -484,6 +538,8 @@ static inline int tracehook_get_signal(s
   */
  static inline int tracehook_notify_jctl(int notify, int why)
  {
@@ -868,7 +878,7 @@
  	return notify || (current->ptrace & PT_PTRACED);
  }
  
-@@ -507,6 +560,8 @@ static inline int tracehook_notify_jctl(
+@@ -507,6 +563,8 @@ static inline int tracehook_notify_jctl(
  static inline int tracehook_notify_death(struct task_struct *task,
  					 void **death_cookie, int group_dead)
  {
@@ -877,7 +887,7 @@
  	if (task->exit_signal == -1)
  		return task->ptrace ? SIGCHLD : DEATH_REAP;
  
-@@ -543,6 +598,10 @@ static inline void tracehook_report_deat
+@@ -543,6 +601,10 @@ static inline void tracehook_report_deat
  					  int signal, void *death_cookie,
  					  int group_dead)
  {
@@ -888,7 +898,7 @@
  }
  
  #ifdef TIF_NOTIFY_RESUME
-@@ -572,10 +631,14 @@ static inline void set_notify_resume(str
+@@ -572,10 +634,14 @@ static inline void set_notify_resume(str
   * asynchronously, this will be called again before we return to
   * user mode.
   *
@@ -906,10 +916,10 @@
  
 diff --git a/include/linux/utrace.h b/include/linux/utrace.h
 new file mode 100644
-index ...61ba640 100644  
+index ...76cdb73 100644  
 --- /dev/null
 +++ b/include/linux/utrace.h
-@@ -0,0 +1,705 @@
+@@ -0,0 +1,707 @@
 +/*
 + * utrace infrastructure interface for debugging user processes
 + *
@@ -1010,6 +1020,8 @@
 +	__attribute__((weak));
 +void utrace_report_clone(unsigned long, struct task_struct *)
 +	__attribute__((weak));
++void utrace_finish_vfork(struct task_struct *)
++	__attribute__((weak));
 +void utrace_report_exit(long *exit_code)
 +	__attribute__((weak));
 +void utrace_report_death(struct task_struct *, struct utrace *, bool, int)
@@ -2432,10 +2444,10 @@
  			  struct pt_regs *regs, void *cookie)
 diff --git a/kernel/utrace.c b/kernel/utrace.c
 new file mode 100644
-index ...1b794bb 100644  
+index ...22640e5 100644  
 --- /dev/null
 +++ b/kernel/utrace.c
-@@ -0,0 +1,2538 @@
+@@ -0,0 +1,2570 @@
 +/*
 + * utrace infrastructure interface for debugging user processes
 + *
@@ -2524,6 +2536,7 @@
 +	unsigned int report:1;
 +	unsigned int interrupt:1;
 +	unsigned int signal_handler:1;
++	unsigned int vfork_stop:1; /* need utrace_stop() before vfork wait */
 +	unsigned int death:1;	/* in utrace_report_death() now */
 +	unsigned int reap:1;	/* release_task() has run */
 +};
@@ -4114,6 +4127,37 @@
 +	       report_clone, clone_flags, child);
 +
 +	utrace->u.live.cloning = NULL;
++
++	/*
++	 * For a vfork, we will go into an uninterruptible block waiting
++	 * for the child.  We need UTRACE_STOP to happen before this, not
++	 * after.  For CLONE_VFORK, utrace_finish_vfork() will be called.
++	 */
++	if (report.action == UTRACE_STOP && (clone_flags & CLONE_VFORK)) {
++		spin_lock(&utrace->lock);
++		utrace->vfork_stop = 1;
++		spin_unlock(&utrace->lock);
++	}
++}
++
++/*
++ * We're called after utrace_report_clone() for a CLONE_VFORK.
++ * If UTRACE_STOP was left from the clone report, we stop here.
++ * After this, we'll enter the uninterruptible wait_for_completion()
++ * waiting for the child.
++ */
++void utrace_finish_vfork(struct task_struct *task)
++{
++	struct utrace *utrace = task->utrace;
++
++	spin_lock(&utrace->lock);
++	if (!utrace->vfork_stop)
++		spin_unlock(&utrace->lock);
++	else {
++		utrace->vfork_stop = 0;
++		spin_unlock(&utrace->lock);
++		utrace_stop(task, utrace);
++	}
 +}
 +
 +/*




More information about the fedora-extras-commits mailing list