Commit ab1c23c2 authored by Bodo Stroesser's avatar Bodo Stroesser Committed by Linus Torvalds

[PATCH] SYSEMU: fix sysaudit / singlestep interaction

      Paolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>

This is simply an adjustment for "Ptrace - i386: fix Syscall Audit interaction
with singlestep" to work on top of SYSEMU patches, too.  On this patch, I have
some doubts: I wonder why we need to alter that way ptrace_disable().

I left the patch this way because it has been extensively tested, but I don't
understand the reason.

The current PTRACE_DETACH handling simply clears child->ptrace; actually this
is not enough because entry.S just looks at the thread_flags; actually,
do_syscall_trace checks current->ptrace but I don't think depending on that is
good, at least for performance, so I think the clearing is done elsewhere.
For instance, on PTRACE_CONT it's done, but doing PTRACE_DETACH without
PTRACE_CONT is possible (and happens when gdb crashes and one kills it
manually).
Signed-off-by: default avatarPaolo 'Blaisorblade' Giarrusso <blaisorblade@yahoo.it>
CC: Roland McGrath <roland@redhat.com>
Cc: Jeff Dike <jdike@addtoit.com>
Signed-off-by: default avatarAndrew Morton <akpm@osdl.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@osdl.org>
parent 1b38f006
...@@ -271,6 +271,8 @@ static void clear_singlestep(struct task_struct *child) ...@@ -271,6 +271,8 @@ static void clear_singlestep(struct task_struct *child)
void ptrace_disable(struct task_struct *child) void ptrace_disable(struct task_struct *child)
{ {
clear_singlestep(child); clear_singlestep(child);
clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
} }
/* /*
...@@ -693,14 +695,29 @@ __attribute__((regparm(3))) ...@@ -693,14 +695,29 @@ __attribute__((regparm(3)))
int do_syscall_trace(struct pt_regs *regs, int entryexit) int do_syscall_trace(struct pt_regs *regs, int entryexit)
{ {
int is_sysemu = test_thread_flag(TIF_SYSCALL_EMU), ret = 0; int is_sysemu = test_thread_flag(TIF_SYSCALL_EMU), ret = 0;
/* With TIF_SYSCALL_EMU set we want to ignore TIF_SINGLESTEP */ /* With TIF_SYSCALL_EMU set we want to ignore TIF_SINGLESTEP for syscall
* interception. */
int is_singlestep = !is_sysemu && test_thread_flag(TIF_SINGLESTEP); int is_singlestep = !is_sysemu && test_thread_flag(TIF_SINGLESTEP);
/* do the secure computing check first */ /* do the secure computing check first */
secure_computing(regs->orig_eax); secure_computing(regs->orig_eax);
if (unlikely(current->audit_context) && entryexit) if (unlikely(current->audit_context)) {
audit_syscall_exit(current, AUDITSC_RESULT(regs->eax), regs->eax); if (entryexit)
audit_syscall_exit(current, AUDITSC_RESULT(regs->eax), regs->eax);
/* Debug traps, when using PTRACE_SINGLESTEP, must be sent only
* on the syscall exit path. Normally, when TIF_SYSCALL_AUDIT is
* not used, entry.S will call us only on syscall exit, not
* entry; so when TIF_SYSCALL_AUDIT is used we must avoid
* calling send_sigtrap() on syscall entry.
*
* Note that when PTRACE_SYSEMU_SINGLESTEP is used,
* is_singlestep is false, despite his name, so we will still do
* the correct thing.
*/
else if (is_singlestep)
goto out;
}
if (!(current->ptrace & PT_PTRACED)) if (!(current->ptrace & PT_PTRACED))
goto out; goto out;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment