[PATCH 75] don't detach the engine with the parting signal

Oleg Nesterov oleg at redhat.com
Fri Oct 9 17:09:10 UTC 2009


The parting signal must not be visible to the next attacher.
Compatibility!

Change ptrace_detach_task() to set context->resume = UTRACE_DETACH and
do utrace_control(UTRACE_RESUME) in case the tracee should process the
signal.

If the tracee is killed we don't care what will happen. Otherwise it
ptrace_report_signal(UTRACE_SIGNAL_REPORT) must be called, it will
return UTRACE_DETACH and complete the detach.

TODO:

	- re-check UTRACE_SIGNAL_HANDLER is not possible

	- info->si_pid will be wrong if sig != si_signo.
	  how can we fix this? can't we ignore the problem?
	  upstream is buggy too, I hope we can

	- the next attach is not possible until the tracee
	  does ptrace_report_signal(). Fixed by the next
	  patches.

---

 kernel/ptrace.c |   21 ++++++++++++++-------
 1 file changed, 14 insertions(+), 7 deletions(-)

--- PU/kernel/ptrace.c~75_DETACHED_ENGINE	2009-10-09 16:49:32.000000000 +0200
+++ PU/kernel/ptrace.c	2009-10-09 17:14:30.000000000 +0200
@@ -87,9 +87,12 @@ static struct utrace_engine *ptrace_look
 					&ptrace_utrace_ops, NULL);
 }
 
-static void detach_signal(struct task_struct *tracee,
+static enum utrace_resume_action
+detach_signal(struct task_struct *tracee,
 				struct ptrace_context *context, int sig)
 {
+	enum utrace_resume_action action = UTRACE_DETACH;
+
 	switch (get_stop_event(context)) {
 	case PTRACE_EVENT_SYSCALL_ENTRY:
 	case PTRACE_EVENT_SYSCALL_EXIT:
@@ -98,26 +101,30 @@ static void detach_signal(struct task_st
 		break;
 
 	case PTRACE_EVENT_SIGNAL:
-		if (!valid_signal(sig))
-			sig = context->signr;
-		if (sig)
-			send_sig_info(sig, SEND_SIG_PRIV, tracee);
+		if (valid_signal(sig))
+			context->signr = sig;
+		context->stop_code = 0;
+		context->resume = UTRACE_DETACH;
+		action = UTRACE_RESUME;
 		break;
 	}
+
+	return action;
 }
 
 static void ptrace_detach_task(struct task_struct *child, int sig)
 {
 	struct utrace_engine *engine = ptrace_lookup_engine(child);
+	enum utrace_resume_action action = UTRACE_DETACH;
 	int ret;
 
 	if (unlikely(IS_ERR(engine)))
 		return;
 
 	if (sig)
-		detach_signal(child, ptrace_context(engine), sig);
+		action = detach_signal(child, ptrace_context(engine), sig);
 
-	ret = utrace_control(child, engine, UTRACE_DETACH);
+	ret = utrace_control(child, engine, action);
 	WARN_ON(ret && ret != -EINPROGRESS &&
 		ret != -ESRCH && ret != -EALREADY);
 




More information about the utrace-devel mailing list