[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