From: Oleg Nesterov <oleg@redhat.com>
To: Roland McGrath <roland@redhat.com>,
Andrew Morton <akpm@linux-foundation.org>
Cc: Evan Teran <eteran@alum.rit.edu>,
Jan Kratochvil <jan.kratochvil@redhat.com>,
linux-kernel@vger.kernel.org
Subject: [PATCH 1/1] ptrace: x86: stepping in a signal handler leaks X86_EFLAGS_TF
Date: Sun, 6 Jun 2010 18:39:28 +0200 [thread overview]
Message-ID: <20100606163928.GB19800@redhat.com> (raw)
In-Reply-To: <20100606163848.GA19800@redhat.com>
See https://bugzilla.kernel.org/show_bug.cgi?id=16061
When the TIF_SINGLESTEP tracee dequeues a signal, handle_signal()
clears TIF_FORCED_TF and X86_EFLAGS_TF but leaves TIF_SINGLESTEP set.
If the tracer does PTRACE_SINGLESTEP again, enable_single_step() sets
X86_EFLAGS_TF but not TIF_FORCED_TF. This means that the subsequent
PTRACE_CONT doesn't not clear X86_EFLAGS_TF, and the tracee gets the
wrong SIGTRAP.
Test-case (based on the excellent report from Evan):
#include <unistd.h>
#include <stdio.h>
#include <sys/ptrace.h>
#include <sys/wait.h>
#include <sys/user.h>
#include <assert.h>
#include <stddef.h>
void handler(int n)
{
asm("nop");
}
int child(void)
{
assert(ptrace(PTRACE_TRACEME, 0,0,0) == 0);
signal(SIGALRM, handler);
kill(getpid(), SIGALRM);
return 0x23;
}
void *getip(int pid)
{
return (void*)ptrace(PTRACE_PEEKUSER, pid,
offsetof(struct user, regs.rip), 0);
}
int main(void)
{
int pid, status;
pid = fork();
if (!pid)
return child();
assert(wait(&status) == pid);
assert(WIFSTOPPED(status) && WSTOPSIG(status) == SIGALRM);
assert(ptrace(PTRACE_SINGLESTEP, pid, 0, SIGALRM) == 0);
assert(wait(&status) == pid);
assert(WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP);
assert((getip(pid) - (void*)handler) == 0);
assert(ptrace(PTRACE_SINGLESTEP, pid, 0, SIGALRM) == 0);
assert(wait(&status) == pid);
assert(WIFSTOPPED(status) && WSTOPSIG(status) == SIGTRAP);
assert((getip(pid) - (void*)handler) == 1);
assert(ptrace(PTRACE_CONT, pid, 0,0) == 0);
assert(wait(&status) == pid);
assert(WIFEXITED(status) && WEXITSTATUS(status) == 0x23);
return 0;
}
Change handle_signal() to clear TIF_SINGLESTEP as well. We cleared
X86_EFLAGS_TF and TIF_FORCED_TF, we are not going to return to user-mode
if TIF_SINGLESTEP was set, and we already passed syscall_trace_leave().
We are going to sleep until the next ptrace_resume() which should set
these flags correctly if needed.
Note: this is the most simple fix now, most probably we need more
changes/cleanups on top of this patch.
Reported-by: Evan Teran <eteran@alum.rit.edu>
Signed-off-by: Oleg Nesterov <oleg@redhat.com>
---
arch/x86/kernel/signal.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- 34-rc1/arch/x86/kernel/signal.c~BZ16061_TEMPORARY_FIX 2010-06-06 16:22:55.000000000 +0200
+++ 34-rc1/arch/x86/kernel/signal.c 2010-06-06 16:47:55.000000000 +0200
@@ -749,7 +749,7 @@ handle_signal(unsigned long sig, siginfo
spin_unlock_irq(¤t->sighand->siglock);
tracehook_signal_handler(sig, info, ka, regs,
- test_thread_flag(TIF_SINGLESTEP));
+ test_and_clear_thread_flag(TIF_SINGLESTEP));
return 0;
}
next prev parent reply other threads:[~2010-06-06 16:40 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-06-02 19:23 Bug 16061 - single stepping in a signal handler can cause the single step flag to get "stuck" Oleg Nesterov
2010-06-02 20:07 ` Oleg Nesterov
2010-06-06 16:38 ` [PATCH 0/1] ptrace: x86: stepping in a signal handler leaks X86_EFLAGS_TF Oleg Nesterov
2010-06-06 16:39 ` Oleg Nesterov [this message]
2010-06-16 2:31 ` Bug 16061 - single stepping in a signal handler can cause the single step flag to get "stuck" Roland McGrath
2010-06-16 19:56 ` Oleg Nesterov
2010-06-16 20:53 ` Roland McGrath
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=20100606163928.GB19800@redhat.com \
--to=oleg@redhat.com \
--cc=akpm@linux-foundation.org \
--cc=eteran@alum.rit.edu \
--cc=jan.kratochvil@redhat.com \
--cc=linux-kernel@vger.kernel.org \
--cc=roland@redhat.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.