The Linux Kernel Mailing List
 help / color / mirror / Atom feed
From: Ingo Molnar <mingo@elte.hu>
To: eranian@googlemail.com
Cc: linux-kernel@vger.kernel.org, akpm@linux-foundation.org,
	x86@kernel.org, andi@firstfloor.org, eranian@gmail.com,
	sfr@canb.auug.org.au, Roland McGrath <roland@redhat.com>,
	Oleg Nesterov <oleg@redhat.com>
Subject: Re: [patch 20/24] perfmon: system calls interface
Date: Wed, 26 Nov 2008 15:00:27 +0100	[thread overview]
Message-ID: <20081126140027.GC6562@elte.hu> (raw)
In-Reply-To: <492d0c0b.170e660a.15ba.ffffdabf@mx.google.com>


* eranian@googlemail.com <eranian@googlemail.com> wrote:

> +static int pfm_task_incompatible(struct pfm_context *ctx,
> +				 struct task_struct *task)
> +{
> +	/*
> +	 * cannot attach to a kernel thread
> +	 */
> +	if (!task->mm) {
> +		PFM_DBG("cannot attach to kernel thread [%d]", task->pid);
> +		return -EPERM;
> +	}
> +
> +	/*
> +	 * cannot attach to a zombie task
> +	 */
> +	if (task->exit_state == EXIT_ZOMBIE || task->exit_state == EXIT_DEAD) {
> +		PFM_DBG("cannot attach to zombie/dead task [%d]", task->pid);
> +		return -EBUSY;
> +	}
> +	return 0;
> +}

The ptrace coupling code seems broken.

It is used in the following context:

+       /*
+        * returns 0 if cannot attach
+        */
+       ret1 = ptrace_may_access(p, PTRACE_MODE_ATTACH);
+       if (ret1)
+               ret = ptrace_check_attach(p, 0);
+
+       PFM_DBG("may_attach=%d check_attach=%d", ret1, ret);
+
+       if (ret || !ret1)
+               goto error;
+
+       ret = pfm_task_incompatible(ctx, p);
+       if (ret)
+               goto error;

firstly, this code is critical to security, but the variable naming 
and the control flow is shaped in a dangerous and error-prone way: two 
opaque 'ret' and 'ret1' names, which have _inverted_ logical meaning: 
for 'ret' a nonzero value means an error, for 'ret1' a zero value 
means error.

This code _must_ be rewritten cleanly via a single 'err' variable. 
There's absolutely no need to nest ret and ret1 here. If we may not 
access via ptrace then we should error out pronto and not complicate 
the flow.

Secondly, get rid of those PFM_DBG() calls there, they are not needed 
in a production kernel and just obscure review.

Thirdly, the check for ->exit_state in pfm_task_incompatible() is not 
needed: we've just passed ptrace_check_attach() so we know we just 
transitioned the task to task->state == TASK_TRACED.

If you _ever_ see a task exit TASK_TRACED and go zombie or dead from 
there without this code allowing it that means the whole state machine 
with ptrace is borked up by perfmon. For example i dont see where the 
perfmon-control task parents itself as the exclusive debugger (parent) 
of the debuggee-task.

Without that being implemented properly, a parallel ptrace / perfmon 
scenario (triggerable by unprivileged userspace) can go amok, crash 
the kernel and likely open up various rootholes as well. The kludge in 
pfm_task_incompatible() shows that this was probably seen in the field 
and hacked around.

	Ingo

  parent reply	other threads:[~2008-11-26 14:01 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-11-26  8:42 [patch 20/24] perfmon: system calls interface eranian
2008-11-26 12:02 ` Andi Kleen
2008-11-26 13:43 ` Ingo Molnar
2008-11-26 14:00 ` Ingo Molnar [this message]
2008-11-26 16:59   ` Oleg Nesterov
2008-11-27 12:25     ` stephane eranian
2008-11-27 12:41       ` Andi Kleen
2008-11-27 14:22   ` stephane eranian
2008-11-27 14:42     ` Ingo Molnar
2008-11-27 15:16       ` stephane eranian
2008-12-01  0:49     ` Paul Mackerras
2008-12-01  6:05       ` stephane eranian
2008-12-03  2:02   ` Roland McGrath
2008-12-04  1:05   ` Roland McGrath
2008-11-26 14:02 ` Ingo Molnar
2008-11-26 14:08 ` Ingo Molnar
2008-11-27 14:28   ` stephane eranian
2008-11-26 14:11 ` Ingo Molnar
2008-11-26 14:13 ` Ingo Molnar
2008-11-27 14:01 ` Thomas Gleixner
2008-11-27 14:07   ` stephane eranian
2008-12-01  6:10   ` stephane eranian
  -- strict thread matches above, loose matches on Subject: below --
2008-11-25 21:36 eranian

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20081126140027.GC6562@elte.hu \
    --to=mingo@elte.hu \
    --cc=akpm@linux-foundation.org \
    --cc=andi@firstfloor.org \
    --cc=eranian@gmail.com \
    --cc=eranian@googlemail.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=oleg@redhat.com \
    --cc=roland@redhat.com \
    --cc=sfr@canb.auug.org.au \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox