1. ptrace_set_syscall_trace(true)->set_tsk_thread_flag(TIF_SYSCALL_TRACE) can race with utrace_control()->utrace_reset() path which can miss PT_SYSCALL_TRACE and clear TIF_SYSCALL_TRACE after it was already set. 2. ptrace_set_syscall_trace(false) clears TIF_SYSCALL_TRACE and this is not utrace-friendly, it can need this flag. Change ptrace_set_syscall_trace() to take task_utrace_lock(), this is enough to fix the 1st problem. Check task_utrace_flags() before clearing TIF_SYSCALL_TRACE, this fixes 2. Signed-off-by: Oleg Nesterov <oleg@xxxxxxxxxx> --- kernel/ptrace.c | 6 +++++- 1 files changed, 5 insertions(+), 1 deletions(-) diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 7deb292..69850e9 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -24,6 +24,7 @@ #include <linux/regset.h> #include <linux/hw_breakpoint.h> #include <linux/cn_proc.h> +#include <linux/utrace.h> void ptrace_signal_wake_up(struct task_struct *p, int quiescent) { @@ -40,13 +41,16 @@ void ptrace_signal_wake_up(struct task_struct *p, int quiescent) static void ptrace_set_syscall_trace(struct task_struct *p, bool on) { + task_utrace_lock(p); if (on) { p->ptrace |= PT_SYSCALL_TRACE; set_tsk_thread_flag(p, TIF_SYSCALL_TRACE); } else { p->ptrace &= ~PT_SYSCALL_TRACE; - clear_tsk_thread_flag(p, TIF_SYSCALL_TRACE); + if (!(task_utrace_flags(p) & UTRACE_EVENT_SYSCALL)) + clear_tsk_thread_flag(p, TIF_SYSCALL_TRACE); } + task_utrace_unlock(p); } static int ptrace_trapping_sleep_fn(void *flags) -- 1.5.5.1 _______________________________________________ kernel mailing list kernel@xxxxxxxxxxxxxxxxxxxxxxx https://admin.fedoraproject.org/mailman/listinfo/kernel