Q: utrace_attach_task && utrace_release_task

Oleg Nesterov oleg at redhat.com
Wed Mar 4 21:27:35 UTC 2009


On 03/03, Roland McGrath wrote:
>
> I would rather not touch the tracehook interfaces now.  You are indeed
> right that the motivation for this had to do with the utrace-indirect code.
> As I've said, I do intend to resurrect that code and send it upstream later
> on.  We can consider cleanups then.  For now, let's not do anything
> preemptively that is likely to introduce a new need to touch non-utrace
> code again later.

OK, understand, thanks.

A couple of questions...

utrace_attach_task() checks ->exit_state == EXIT_DEAD. Why? I mean,
how can it help, we don't hold any locks, target can change its
->exit_state right after the check.

So, looks like we can attach to the EXIT_DEAD target. Is it safe?
The only in-kernel user of utrace is ptrace, in that case I _think_
we are safe, we should notice that the task is dead later, for
example in get_utrace_lock(), and do UTRACE_DETACH. But in general,
is it OK?

Hmm... utrace_release_task() checks only ->attached, I can't understand
why it ignores ->attaching. Let's suppose we are doing PTRACE_ATTACH to
the exiting task, isn't it possible to leak the attached engine?

I don't understand why utrace_release_task() doesn't set ->reap = 1
unconditionally. In that case we could use this flag instead of
EXIT_DEAD to verify it is "safe" to attach or get_utrace_lock().

Back to utrace_attach_task(),

static inline int utrace_attach_delay(struct task_struct *target)
{
	if (target->flags & PF_STARTING) {
		struct utrace *utrace = task_utrace_struct(current);
		if (!utrace || utrace->cloning != target) {
			yield();
			if (signal_pending(current))
				return -ERESTARTNOINTR;
			return -EAGAIN;

Why does it call yield() before returning the error? This looks
really strange. And what is the point to check signal_pending()
here?

(btw, "!utrace" above is not possible).

Oleg.




More information about the utrace-devel mailing list