From: Oleg Nesterov <oleg@redhat.com>
To: Salman Qazi <sqazi@google.com>
Cc: taviso@google.com, Roland Dreier <rolandd@cisco.com>,
Andrew Morton <akpm@linux-foundation.org>,
Roland McGrath <roland@redhat.com>,
linux-kernel@vger.kernel.org
Subject: Re: Race in ptrace.
Date: Thu, 11 Feb 2010 13:56:07 +0100 [thread overview]
Message-ID: <20100211125607.GA5086@redhat.com> (raw)
In-Reply-To: <4352991a1002101038s6a2e67d9mc373416c17de9e6a@mail.gmail.com>
On 02/10, Salman Qazi wrote:
>
> I have
> made a simpler version of tavis's test case:
Thanks, now I see what you mean.
But this all is correct, you can't expect PTRACE_SYSCALL can succeed
is the tracee is running, it must be stopped or traced.
The tracee is running because it was TASK_STOPPED and antagonist()
sends SIGCONT.
The tracee was TASK_STOPPED because the tracer passes sig = SIGSTOP
via ptrace(PTRACE_SYSCALL, WSTOPSIG(status).
Where do you see the bug?
OK, let me simplify the test-case even more:
int main(void)
{
int stat, ret;
int pid = fork();
if (!pid) {
ptrace(PTRACE_TRACEME, 0, NULL, NULL);
for (;;)
;
}
sleep(1); // wait for PTRACE_TRACEME
kill(pid, SIGSTOP);
// the child reports SIGSTOP, it is TASK_TRACED
assert(pid == wait(&stat) && WIFSTOPPED(stat));
// the tracee should stop, we pass sig = SIGSTOP
assert(ptrace(PTRACE_SYSCALL, pid, 0, WSTOPSIG(stat)) == 0);
// the child reports the group stop, it is TASK_STOPPED
assert(pid == wait(&stat) && WIFSTOPPED(stat));
// the tracee is STOPPED as requested, not TRACED,
// SIGCONT wakes it up
kill(pid, SIGCONT);
// now the tracee is _running_, and PTRACE_SYSCALL must fail
ret = ptrace(PTRACE_SYSCALL, pid, 0, WSTOPSIG(stat));
printf("should fail: ret=%d %m\n", ret);
return 0;
}
PTRACE_SYSCALL fails, and this is absolutely correct.
Now, let's look at your test-case
> int main(int argc, char **argv)
> {
> int status;
> assert((child_pid = do_fork(child)) > 0);
> assert((ant_pid = do_fork(antagonist)) > 0);
> waitpid(child_pid, &status, 0);
> ptrace(PTRACE_SYSCALL, child_pid, NULL, NULL);
> while(1) {
> if (waitpid(child_pid, &status, 0) <= 0) {
> printf("Errno %d\n", errno);
> exit(EXIT_FAILURE);
> }
> if (WIFSTOPPED(status)) {
WSTOPSIG() should be either SIGCONT or SIGSTOP
> printf("stopped: %d\n", WSTOPSIG(status));
>
> /* This should work, but sometimes it doesn't */
> if (ptrace(PTRACE_SYSCALL, child_pid,
> NULL, WSTOPSIG(status)) < 0) {
This should not work if the tracee reported the group stop (not the
fact it dequeued SIGSTOP) and antagonist() sends SIGCONT in between.
> /* Oddly it works the second time! */
> assert (ptrace(PTRACE_SYSCALL,
> child_pid, NULL, WSTOPSIG(status)) < 0);
Of couse, it _can_ work the second time, antagonist() sends a signal
(SIGCONT or SIGSTOP), the tracee dequeues the signal, and stops to
report this signal.
See?
Oleg.
next prev parent reply other threads:[~2010-02-11 12:56 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-02-08 22:16 Race in ptrace Salman Qazi
[not found] ` <20100208143231.6d804590.akpm@linux-foundation.org>
2010-02-09 11:27 ` Oleg Nesterov
2010-02-10 13:35 ` Oleg Nesterov
2010-02-10 18:38 ` Salman Qazi
2010-02-11 12:56 ` Oleg Nesterov [this message]
2010-02-11 16:32 ` Salman Qazi
2010-02-11 16:50 ` Oleg Nesterov
2010-02-11 18:43 ` Salman Qazi
2010-02-11 18:55 ` Oleg Nesterov
2010-02-11 19:08 ` Salman Qazi
2010-02-11 20:10 ` Oleg Nesterov
2010-02-11 20:39 ` Salman Qazi
2010-02-11 20:55 ` Roland McGrath
2010-02-11 21:05 ` Salman Qazi
2010-02-11 20:59 ` Oleg Nesterov
-- strict thread matches above, loose matches on Subject: below --
2010-02-08 22:04 Salman Qazi
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=20100211125607.GA5086@redhat.com \
--to=oleg@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=roland@redhat.com \
--cc=rolandd@cisco.com \
--cc=sqazi@google.com \
--cc=taviso@google.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.