[PATCH 04] shift ptrace_utrace_exit() from tracehook_report_exit() to exit_ptrace()

Oleg Nesterov oleg at redhat.com
Thu Aug 13 17:12:21 UTC 2009


tracehook_report_exit() calls ptrace_utrace_exit() to early. We don't
have PF_EXITING yet, we can race with ptrace_traceme().

Granted, exit_ptrace/ptrace_utrace_exit should be reworked later. Just
a minimal fix for now.

---

 include/linux/ptrace.h    |    2 --
 include/linux/tracehook.h |    2 --
 kernel/ptrace.c           |   20 +++++++++++---------
 3 files changed, 11 insertions(+), 13 deletions(-)

--- PU/include/linux/ptrace.h~04_PTRACE_EXIT	2009-08-13 15:19:18.000000000 +0200
+++ PU/include/linux/ptrace.h	2009-08-13 17:53:02.000000000 +0200
@@ -131,8 +131,6 @@ static inline int task_ptrace(struct tas
 	return task->ptrace;
 }
 
-extern void ptrace_utrace_exit(struct task_struct *);
-
 /**
  * ptrace_init_task - initialize ptrace state for a new child
  * @child:		new child task
--- PU/include/linux/tracehook.h~04_PTRACE_EXIT	2009-08-13 15:50:27.000000000 +0200
+++ PU/include/linux/tracehook.h	2009-08-13 17:51:52.000000000 +0200
@@ -195,8 +195,6 @@ static inline void tracehook_report_exit
 {
 	if (unlikely(task_utrace_flags(current) & UTRACE_EVENT(EXIT)))
 		utrace_report_exit(exit_code);
-	if (unlikely(!list_empty(&current->ptraced)))
-		ptrace_utrace_exit(current);
 }
 
 /**
--- PU/kernel/ptrace.c~04_PTRACE_EXIT	2009-08-13 17:35:29.000000000 +0200
+++ PU/kernel/ptrace.c	2009-08-13 17:55:13.000000000 +0200
@@ -70,15 +70,6 @@ static void ptrace_detach_task(struct ta
 	utrace_engine_put(engine);
 }
 
-void ptrace_utrace_exit(struct task_struct *task)
-{
-	struct task_struct *child;
-	read_lock(&tasklist_lock);
-	list_for_each_entry(child, &task->ptraced, ptrace_entry)
-		ptrace_detach_task(child, 0);
-	read_unlock(&tasklist_lock);
-}
-
 /*
  * unptrace a task: move it back to its original parent and
  * remove it from the ptrace list.
@@ -810,6 +801,15 @@ int ptrace_detach(struct task_struct *ch
 	return 0;
 }
 
+static void ptrace_utrace_exit(struct task_struct *task)
+{
+	struct task_struct *child;
+	read_lock(&tasklist_lock);
+	list_for_each_entry(child, &task->ptraced, ptrace_entry)
+		ptrace_detach_task(child, 0);
+	read_unlock(&tasklist_lock);
+}
+
 /*
  * Detach all tasks we were using ptrace on.
  */
@@ -818,6 +818,8 @@ void exit_ptrace(struct task_struct *tra
 	struct task_struct *p, *n;
 	LIST_HEAD(ptrace_dead);
 
+	ptrace_utrace_exit(tracer);
+
 	write_lock_irq(&tasklist_lock);
 	list_for_each_entry_safe(p, n, &tracer->ptraced, ptrace_entry) {
 		if (__ptrace_detach(tracer, p))




More information about the utrace-devel mailing list