|
From: Bodo S. <bst...@fu...> - 2004-10-21 08:22:19
|
Bodo Stroesser wrote:
> The patch is tested, AFAICS, it works fine, i.e. sysemu can be switched on and
> off dynamically without crash.
>
Here is a new version of the patch. I changed it to use TIF_SYSCALL_EMU
instead of TIF_SINGLETSTEP. This is more intuitive, I think.
Bodo
---
--- a/arch/i386/kernel/ptrace.c 2004-10-20 16:57:25.000000000 +0200
+++ b/arch/i386/kernel/ptrace.c 2004-10-21 09:55:00.000000000 +0200
@@ -585,7 +585,7 @@
__attribute__((regparm(3)))
int do_syscall_trace(struct pt_regs *regs, int entryexit)
{
- int is_sysemu;
+ int is_sysemu, is_systrace;
if (unlikely(current->audit_context)) {
if (!entryexit)
audit_syscall_entry(current, regs->orig_eax,
@@ -595,9 +595,19 @@
audit_syscall_exit(current, regs->eax);
}
is_sysemu = test_thread_flag(TIF_SYSCALL_EMU);
+ is_systrace = test_thread_flag(TIF_SYSCALL_TRACE);
- if (!test_thread_flag(TIF_SYSCALL_TRACE) && !is_sysemu)
+ if (!is_systrace && !is_sysemu)
return 0;
+ /* We can detect the case of coming from PTRACE_SYSEMU and now
+ * running with PTRACE_SYSCALL, by TIF_SYSCALL_EMU being set
+ * additionally.
+ * If so let's reset the flag and return without action.
+ */
+ if (is_sysemu && is_systrace) {
+ clear_thread_flag(TIF_SYSCALL_EMU);
+ return 0;
+ }
if (!(current->ptrace & PT_PTRACED))
return 0;
/* the 0x80 provides a way for the tracing parent to distinguish
@@ -605,6 +615,15 @@
ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD)
? 0x80 : 0));
+ /* If we came here with PTRACE_SYSEMU and now continue with
+ * PTRACE_SYSCALL, entry.S used to intercept the syscall return. But it
+ * shouldn't!
+ * So we additionally use TIF_SYSCALL_EMU, which is always unused in this
+ * special case, to remember, we came from SYSEMU.
+ */
+ if (is_sysemu && test_thread_flag(TIF_SYSCALL_TRACE))
+ set_thread_flag(TIF_SYSCALL_EMU);
+
/*
* this isn't the same as continuing with a signal, but it will do
* for normal use. strace only continues with a signal if the
|