Currently tracehooks assume that if the ptraced task has TIF_SYSCALL_TRACE set, the tracee should report the syscall. This is not true, this thread flag can be set by utrace.
Add the new internal ptrace flag, PT_SYSCALL_TRACE. Change ptrace_set_syscall_trace() to set/clear this bit along with TIF_SYSCALL_TRACE, change ptrace_report_syscall() to check this flag instead of PT_PTRACED. Signed-off-by: Oleg Nesterov <o...@redhat.com> --- include/linux/ptrace.h | 3 +++ include/linux/tracehook.h | 2 +- kernel/ptrace.c | 7 +++++-- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/include/linux/ptrace.h b/include/linux/ptrace.h index 9178d5c..98d995d 100644 --- a/include/linux/ptrace.h +++ b/include/linux/ptrace.h @@ -90,6 +90,8 @@ #define PT_TRACE_MASK 0x000003f4 +#define PT_SYSCALL_TRACE 0x00010000 + /* single stepping state bits (used on ARM and PA-RISC) */ #define PT_SINGLESTEP_BIT 31 #define PT_SINGLESTEP (1<<PT_SINGLESTEP_BIT) @@ -187,6 +189,7 @@ static inline void ptrace_init_task(struct task_struct *child, bool ptrace) child->ptrace = 0; if (unlikely(ptrace) && (current->ptrace & PT_PTRACED)) { child->ptrace = current->ptrace; + child->ptrace &= ~PT_SYSCALL_TRACE; __ptrace_link(child, current->parent); } diff --git a/include/linux/tracehook.h b/include/linux/tracehook.h index 3c7b6b3..6ce7a37 100644 --- a/include/linux/tracehook.h +++ b/include/linux/tracehook.h @@ -76,7 +76,7 @@ static inline void ptrace_report_syscall(struct pt_regs *regs) { int ptrace = task_ptrace(current); - if (!(ptrace & PT_PTRACED)) + if (!(ptrace & PT_SYSCALL_TRACE)) return; ptrace_notify(SIGTRAP | ((ptrace & PT_TRACESYSGOOD) ? 0x80 : 0)); diff --git a/kernel/ptrace.c b/kernel/ptrace.c index b6fd922..0825a01 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c @@ -39,10 +39,13 @@ static void ptrace_signal_wake_up(struct task_struct *p, int quiescent) static void ptrace_set_syscall_trace(struct task_struct *p, bool on) { - if (on) + if (on) { + p->ptrace |= PT_SYSCALL_TRACE; set_tsk_thread_flag(p, TIF_SYSCALL_TRACE); - else + } else { + p->ptrace &= ~PT_SYSCALL_TRACE; clear_tsk_thread_flag(p, TIF_SYSCALL_TRACE); + } } /* -- 1.5.5.1