ptrace: Create ptrace_report_syscall_{entry,exit} in ptrace.h

Rename tracehook_report_syscall_{entry,exit} to
ptrace_report_syscall_{entry,exit} and place them in ptrace.h

There is no longer any generic tracehook infractructure so make
these ptrace specific functions ptrace specific.

Reviewed-by: Kees Cook <keescook@chromium.org>
Link: https://lkml.kernel.org/r/20220309162454.123006-3-ebiederm@xmission.com
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
This commit is contained in:
Eric W. Biederman 2022-01-27 11:46:37 -06:00
parent 42da6b7e7d
commit 153474ba1a
30 changed files with 109 additions and 126 deletions

View File

@ -217,7 +217,7 @@ config TRACE_IRQFLAGS_SUPPORT
# asm/syscall.h supplying asm-generic/syscall.h interface # asm/syscall.h supplying asm-generic/syscall.h interface
# linux/regset.h user_regset interfaces # linux/regset.h user_regset interfaces
# CORE_DUMP_USE_REGSET #define'd in linux/elf.h # CORE_DUMP_USE_REGSET #define'd in linux/elf.h
# TIF_SYSCALL_TRACE calls tracehook_report_syscall_{entry,exit} # TIF_SYSCALL_TRACE calls ptrace_report_syscall_{entry,exit}
# TIF_NOTIFY_RESUME calls tracehook_notify_resume() # TIF_NOTIFY_RESUME calls tracehook_notify_resume()
# signal delivery calls tracehook_signal_handler() # signal delivery calls tracehook_signal_handler()
# #

View File

@ -15,7 +15,6 @@
#include <linux/user.h> #include <linux/user.h>
#include <linux/security.h> #include <linux/security.h>
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/tracehook.h>
#include <linux/audit.h> #include <linux/audit.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
@ -323,7 +322,7 @@ asmlinkage unsigned long syscall_trace_enter(void)
unsigned long ret = 0; unsigned long ret = 0;
struct pt_regs *regs = current_pt_regs(); struct pt_regs *regs = current_pt_regs();
if (test_thread_flag(TIF_SYSCALL_TRACE) && if (test_thread_flag(TIF_SYSCALL_TRACE) &&
tracehook_report_syscall_entry(current_pt_regs())) ptrace_report_syscall_entry(current_pt_regs()))
ret = -1UL; ret = -1UL;
audit_syscall_entry(regs->r0, regs->r16, regs->r17, regs->r18, regs->r19); audit_syscall_entry(regs->r0, regs->r16, regs->r17, regs->r18, regs->r19);
return ret ?: current_pt_regs()->r0; return ret ?: current_pt_regs()->r0;
@ -334,5 +333,5 @@ syscall_trace_leave(void)
{ {
audit_syscall_exit(current_pt_regs()); audit_syscall_exit(current_pt_regs());
if (test_thread_flag(TIF_SYSCALL_TRACE)) if (test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall_exit(current_pt_regs(), 0); ptrace_report_syscall_exit(current_pt_regs(), 0);
} }

View File

@ -4,7 +4,6 @@
*/ */
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/tracehook.h>
#include <linux/sched/task_stack.h> #include <linux/sched/task_stack.h>
#include <linux/regset.h> #include <linux/regset.h>
#include <linux/unistd.h> #include <linux/unistd.h>
@ -258,7 +257,7 @@ long arch_ptrace(struct task_struct *child, long request,
asmlinkage int syscall_trace_entry(struct pt_regs *regs) asmlinkage int syscall_trace_entry(struct pt_regs *regs)
{ {
if (tracehook_report_syscall_entry(regs)) if (ptrace_report_syscall_entry(regs))
return ULONG_MAX; return ULONG_MAX;
return regs->r8; return regs->r8;
@ -266,5 +265,5 @@ asmlinkage int syscall_trace_entry(struct pt_regs *regs)
asmlinkage void syscall_trace_exit(struct pt_regs *regs) asmlinkage void syscall_trace_exit(struct pt_regs *regs)
{ {
tracehook_report_syscall_exit(regs, 0); ptrace_report_syscall_exit(regs, 0);
} }

View File

@ -22,7 +22,6 @@
#include <linux/hw_breakpoint.h> #include <linux/hw_breakpoint.h>
#include <linux/regset.h> #include <linux/regset.h>
#include <linux/audit.h> #include <linux/audit.h>
#include <linux/tracehook.h>
#include <linux/unistd.h> #include <linux/unistd.h>
#include <asm/syscall.h> #include <asm/syscall.h>
@ -843,8 +842,8 @@ static void report_syscall(struct pt_regs *regs, enum ptrace_syscall_dir dir)
regs->ARM_ip = dir; regs->ARM_ip = dir;
if (dir == PTRACE_SYSCALL_EXIT) if (dir == PTRACE_SYSCALL_EXIT)
tracehook_report_syscall_exit(regs, 0); ptrace_report_syscall_exit(regs, 0);
else if (tracehook_report_syscall_entry(regs)) else if (ptrace_report_syscall_entry(regs))
current_thread_info()->abi_syscall = -1; current_thread_info()->abi_syscall = -1;
regs->ARM_ip = ip; regs->ARM_ip = ip;

View File

@ -27,7 +27,6 @@
#include <linux/perf_event.h> #include <linux/perf_event.h>
#include <linux/hw_breakpoint.h> #include <linux/hw_breakpoint.h>
#include <linux/regset.h> #include <linux/regset.h>
#include <linux/tracehook.h>
#include <linux/elf.h> #include <linux/elf.h>
#include <asm/compat.h> #include <asm/compat.h>
@ -1818,11 +1817,11 @@ static void report_syscall(struct pt_regs *regs, enum ptrace_syscall_dir dir)
regs->regs[regno] = dir; regs->regs[regno] = dir;
if (dir == PTRACE_SYSCALL_ENTER) { if (dir == PTRACE_SYSCALL_ENTER) {
if (tracehook_report_syscall_entry(regs)) if (ptrace_report_syscall_entry(regs))
forget_syscall(regs); forget_syscall(regs);
regs->regs[regno] = saved_reg; regs->regs[regno] = saved_reg;
} else if (!test_thread_flag(TIF_SINGLESTEP)) { } else if (!test_thread_flag(TIF_SINGLESTEP)) {
tracehook_report_syscall_exit(regs, 0); ptrace_report_syscall_exit(regs, 0);
regs->regs[regno] = saved_reg; regs->regs[regno] = saved_reg;
} else { } else {
regs->regs[regno] = saved_reg; regs->regs[regno] = saved_reg;
@ -1832,7 +1831,7 @@ static void report_syscall(struct pt_regs *regs, enum ptrace_syscall_dir dir)
* tracer modifications to the registers may have rewound the * tracer modifications to the registers may have rewound the
* state machine. * state machine.
*/ */
tracehook_report_syscall_exit(regs, 1); ptrace_report_syscall_exit(regs, 1);
} }
} }

View File

@ -12,7 +12,6 @@
#include <linux/sched/task_stack.h> #include <linux/sched/task_stack.h>
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/tracehook.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/user.h> #include <linux/user.h>
@ -321,7 +320,7 @@ long arch_ptrace(struct task_struct *child, long request,
asmlinkage int syscall_trace_enter(struct pt_regs *regs) asmlinkage int syscall_trace_enter(struct pt_regs *regs)
{ {
if (test_thread_flag(TIF_SYSCALL_TRACE)) if (test_thread_flag(TIF_SYSCALL_TRACE))
if (tracehook_report_syscall_entry(regs)) if (ptrace_report_syscall_entry(regs))
return -1; return -1;
if (secure_computing() == -1) if (secure_computing() == -1)
@ -339,7 +338,7 @@ asmlinkage void syscall_trace_exit(struct pt_regs *regs)
audit_syscall_exit(regs); audit_syscall_exit(regs);
if (test_thread_flag(TIF_SYSCALL_TRACE)) if (test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall_exit(regs, 0); ptrace_report_syscall_exit(regs, 0);
if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
trace_sys_exit(regs, syscall_get_return_value(current, regs)); trace_sys_exit(regs, syscall_get_return_value(current, regs));

View File

@ -12,7 +12,6 @@
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/audit.h> #include <linux/audit.h>
#include <linux/tracehook.h>
#include <linux/regset.h> #include <linux/regset.h>
#include <linux/elf.h> #include <linux/elf.h>
@ -174,7 +173,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
long ret = 0; long ret = 0;
if (test_thread_flag(TIF_SYSCALL_TRACE) && if (test_thread_flag(TIF_SYSCALL_TRACE) &&
tracehook_report_syscall_entry(regs)) ptrace_report_syscall_entry(regs))
/* /*
* Tracing decided this syscall should not happen. * Tracing decided this syscall should not happen.
* We'll return a bogus call number to get an ENOSYS * We'll return a bogus call number to get an ENOSYS
@ -196,5 +195,5 @@ asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
step = test_thread_flag(TIF_SINGLESTEP); step = test_thread_flag(TIF_SINGLESTEP);
if (step || test_thread_flag(TIF_SYSCALL_TRACE)) if (step || test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall_exit(regs, step); ptrace_report_syscall_exit(regs, step);
} }

View File

@ -14,7 +14,7 @@
#include <linux/kdebug.h> #include <linux/kdebug.h>
#include <linux/syscalls.h> #include <linux/syscalls.h>
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/tracehook.h> #include <linux/ptrace.h>
#include <asm/traps.h> #include <asm/traps.h>
#include <asm/vm_fault.h> #include <asm/vm_fault.h>
#include <asm/syscall.h> #include <asm/syscall.h>
@ -348,7 +348,7 @@ void do_trap0(struct pt_regs *regs)
/* allow strace to catch syscall args */ /* allow strace to catch syscall args */
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACE) && if (unlikely(test_thread_flag(TIF_SYSCALL_TRACE) &&
tracehook_report_syscall_entry(regs))) ptrace_report_syscall_entry(regs)))
return; /* return -ENOSYS somewhere? */ return; /* return -ENOSYS somewhere? */
/* Interrupts should be re-enabled for syscall processing */ /* Interrupts should be re-enabled for syscall processing */
@ -386,7 +386,7 @@ void do_trap0(struct pt_regs *regs)
/* allow strace to get the syscall return state */ /* allow strace to get the syscall return state */
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACE))) if (unlikely(test_thread_flag(TIF_SYSCALL_TRACE)))
tracehook_report_syscall_exit(regs, 0); ptrace_report_syscall_exit(regs, 0);
break; break;
case TRAP_DEBUG: case TRAP_DEBUG:

View File

@ -1217,7 +1217,7 @@ syscall_trace_enter (long arg0, long arg1, long arg2, long arg3,
struct pt_regs regs) struct pt_regs regs)
{ {
if (test_thread_flag(TIF_SYSCALL_TRACE)) if (test_thread_flag(TIF_SYSCALL_TRACE))
if (tracehook_report_syscall_entry(&regs)) if (ptrace_report_syscall_entry(&regs))
return -ENOSYS; return -ENOSYS;
/* copy user rbs to kernel rbs */ /* copy user rbs to kernel rbs */
@ -1243,7 +1243,7 @@ syscall_trace_leave (long arg0, long arg1, long arg2, long arg3,
step = test_thread_flag(TIF_SINGLESTEP); step = test_thread_flag(TIF_SINGLESTEP);
if (step || test_thread_flag(TIF_SYSCALL_TRACE)) if (step || test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall_exit(&regs, step); ptrace_report_syscall_exit(&regs, step);
/* copy user rbs to kernel rbs */ /* copy user rbs to kernel rbs */
if (test_thread_flag(TIF_RESTORE_RSE)) if (test_thread_flag(TIF_RESTORE_RSE))

View File

@ -19,7 +19,7 @@
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/user.h> #include <linux/user.h>
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/tracehook.h> #include <linux/ptrace.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <asm/page.h> #include <asm/page.h>
@ -282,13 +282,13 @@ asmlinkage int syscall_trace_enter(void)
int ret = 0; int ret = 0;
if (test_thread_flag(TIF_SYSCALL_TRACE)) if (test_thread_flag(TIF_SYSCALL_TRACE))
ret = tracehook_report_syscall_entry(task_pt_regs(current)); ret = ptrace_report_syscall_entry(task_pt_regs(current));
return ret; return ret;
} }
asmlinkage void syscall_trace_leave(void) asmlinkage void syscall_trace_leave(void)
{ {
if (test_thread_flag(TIF_SYSCALL_TRACE)) if (test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall_exit(task_pt_regs(current), 0); ptrace_report_syscall_exit(task_pt_regs(current), 0);
} }
#endif /* CONFIG_COLDFIRE */ #endif /* CONFIG_COLDFIRE */

View File

@ -33,7 +33,6 @@
#include <linux/elf.h> #include <linux/elf.h>
#include <linux/audit.h> #include <linux/audit.h>
#include <linux/seccomp.h> #include <linux/seccomp.h>
#include <linux/tracehook.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <asm/processor.h> #include <asm/processor.h>
@ -140,7 +139,7 @@ asmlinkage unsigned long do_syscall_trace_enter(struct pt_regs *regs)
secure_computing_strict(regs->r12); secure_computing_strict(regs->r12);
if (test_thread_flag(TIF_SYSCALL_TRACE) && if (test_thread_flag(TIF_SYSCALL_TRACE) &&
tracehook_report_syscall_entry(regs)) ptrace_report_syscall_entry(regs))
/* /*
* Tracing decided this syscall should not happen. * Tracing decided this syscall should not happen.
* We'll return a bogus call number to get an ENOSYS * We'll return a bogus call number to get an ENOSYS
@ -161,7 +160,7 @@ asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
step = test_thread_flag(TIF_SINGLESTEP); step = test_thread_flag(TIF_SINGLESTEP);
if (step || test_thread_flag(TIF_SYSCALL_TRACE)) if (step || test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall_exit(regs, step); ptrace_report_syscall_exit(regs, step);
} }
void ptrace_disable(struct task_struct *child) void ptrace_disable(struct task_struct *child)

View File

@ -27,7 +27,6 @@
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/security.h> #include <linux/security.h>
#include <linux/stddef.h> #include <linux/stddef.h>
#include <linux/tracehook.h>
#include <linux/audit.h> #include <linux/audit.h>
#include <linux/seccomp.h> #include <linux/seccomp.h>
#include <linux/ftrace.h> #include <linux/ftrace.h>
@ -1317,7 +1316,7 @@ asmlinkage long syscall_trace_enter(struct pt_regs *regs, long syscall)
current_thread_info()->syscall = syscall; current_thread_info()->syscall = syscall;
if (test_thread_flag(TIF_SYSCALL_TRACE)) { if (test_thread_flag(TIF_SYSCALL_TRACE)) {
if (tracehook_report_syscall_entry(regs)) if (ptrace_report_syscall_entry(regs))
return -1; return -1;
syscall = current_thread_info()->syscall; syscall = current_thread_info()->syscall;
} }
@ -1376,7 +1375,7 @@ asmlinkage void syscall_trace_leave(struct pt_regs *regs)
trace_sys_exit(regs, regs_return_value(regs)); trace_sys_exit(regs, regs_return_value(regs));
if (test_thread_flag(TIF_SYSCALL_TRACE)) if (test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall_exit(regs, 0); ptrace_report_syscall_exit(regs, 0);
user_enter(); user_enter();
} }

View File

@ -39,7 +39,7 @@ syscall_get_nr(struct task_struct *task, struct pt_regs *regs)
* *
* It's only valid to call this when @task is stopped for system * It's only valid to call this when @task is stopped for system
* call exit tracing (due to TIF_SYSCALL_TRACE or TIF_SYSCALL_AUDIT), * call exit tracing (due to TIF_SYSCALL_TRACE or TIF_SYSCALL_AUDIT),
* after tracehook_report_syscall_entry() returned nonzero to prevent * after ptrace_report_syscall_entry() returned nonzero to prevent
* the system call from taking place. * the system call from taking place.
* *
* This rolls back the register state in @regs so it's as if the * This rolls back the register state in @regs so it's as if the

View File

@ -3,7 +3,6 @@
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/regset.h> #include <linux/regset.h>
#include <linux/tracehook.h>
#include <linux/elf.h> #include <linux/elf.h>
#include <linux/sched/task_stack.h> #include <linux/sched/task_stack.h>
@ -103,7 +102,7 @@ void user_disable_single_step(struct task_struct *child)
asmlinkage int syscall_trace_enter(struct pt_regs *regs) asmlinkage int syscall_trace_enter(struct pt_regs *regs)
{ {
if (test_thread_flag(TIF_SYSCALL_TRACE)) { if (test_thread_flag(TIF_SYSCALL_TRACE)) {
if (tracehook_report_syscall_entry(regs)) if (ptrace_report_syscall_entry(regs))
forget_syscall(regs); forget_syscall(regs);
} }
return regs->syscallno; return regs->syscallno;
@ -113,6 +112,6 @@ asmlinkage void syscall_trace_leave(struct pt_regs *regs)
{ {
int step = test_thread_flag(TIF_SINGLESTEP); int step = test_thread_flag(TIF_SINGLESTEP);
if (step || test_thread_flag(TIF_SYSCALL_TRACE)) if (step || test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall_exit(regs, step); ptrace_report_syscall_exit(regs, step);
} }

View File

@ -15,7 +15,6 @@
#include <linux/regset.h> #include <linux/regset.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/sched/task_stack.h> #include <linux/sched/task_stack.h>
#include <linux/tracehook.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <linux/user.h> #include <linux/user.h>
@ -134,7 +133,7 @@ asmlinkage int do_syscall_trace_enter(void)
int ret = 0; int ret = 0;
if (test_thread_flag(TIF_SYSCALL_TRACE)) if (test_thread_flag(TIF_SYSCALL_TRACE))
ret = tracehook_report_syscall_entry(task_pt_regs(current)); ret = ptrace_report_syscall_entry(task_pt_regs(current));
return ret; return ret;
} }
@ -142,5 +141,5 @@ asmlinkage int do_syscall_trace_enter(void)
asmlinkage void do_syscall_trace_exit(void) asmlinkage void do_syscall_trace_exit(void)
{ {
if (test_thread_flag(TIF_SYSCALL_TRACE)) if (test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall_exit(task_pt_regs(current), 0); ptrace_report_syscall_exit(task_pt_regs(current), 0);
} }

View File

@ -22,7 +22,6 @@
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/audit.h> #include <linux/audit.h>
#include <linux/regset.h> #include <linux/regset.h>
#include <linux/tracehook.h>
#include <linux/elf.h> #include <linux/elf.h>
#include <asm/thread_info.h> #include <asm/thread_info.h>
@ -159,7 +158,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
long ret = 0; long ret = 0;
if (test_thread_flag(TIF_SYSCALL_TRACE) && if (test_thread_flag(TIF_SYSCALL_TRACE) &&
tracehook_report_syscall_entry(regs)) ptrace_report_syscall_entry(regs))
/* /*
* Tracing decided this syscall should not happen. * Tracing decided this syscall should not happen.
* We'll return a bogus call number to get an ENOSYS * We'll return a bogus call number to get an ENOSYS
@ -181,5 +180,5 @@ asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
step = test_thread_flag(TIF_SINGLESTEP); step = test_thread_flag(TIF_SINGLESTEP);
if (step || test_thread_flag(TIF_SYSCALL_TRACE)) if (step || test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall_exit(regs, step); ptrace_report_syscall_exit(regs, step);
} }

View File

@ -15,7 +15,6 @@
#include <linux/elf.h> #include <linux/elf.h>
#include <linux/errno.h> #include <linux/errno.h>
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/tracehook.h>
#include <linux/user.h> #include <linux/user.h>
#include <linux/personality.h> #include <linux/personality.h>
#include <linux/regset.h> #include <linux/regset.h>
@ -316,7 +315,7 @@ long compat_arch_ptrace(struct task_struct *child, compat_long_t request,
long do_syscall_trace_enter(struct pt_regs *regs) long do_syscall_trace_enter(struct pt_regs *regs)
{ {
if (test_thread_flag(TIF_SYSCALL_TRACE)) { if (test_thread_flag(TIF_SYSCALL_TRACE)) {
int rc = tracehook_report_syscall_entry(regs); int rc = ptrace_report_syscall_entry(regs);
/* /*
* As tracesys_next does not set %r28 to -ENOSYS * As tracesys_next does not set %r28 to -ENOSYS
@ -327,7 +326,7 @@ long do_syscall_trace_enter(struct pt_regs *regs)
if (rc) { if (rc) {
/* /*
* A nonzero return code from * A nonzero return code from
* tracehook_report_syscall_entry() tells us * ptrace_report_syscall_entry() tells us
* to prevent the syscall execution. Skip * to prevent the syscall execution. Skip
* the syscall call and the syscall restart handling. * the syscall call and the syscall restart handling.
* *
@ -381,7 +380,7 @@ void do_syscall_trace_exit(struct pt_regs *regs)
#endif #endif
if (stepping || test_thread_flag(TIF_SYSCALL_TRACE)) if (stepping || test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall_exit(regs, stepping); ptrace_report_syscall_exit(regs, stepping);
} }

View File

@ -16,7 +16,7 @@
*/ */
#include <linux/regset.h> #include <linux/regset.h>
#include <linux/tracehook.h> #include <linux/ptrace.h>
#include <linux/audit.h> #include <linux/audit.h>
#include <linux/context_tracking.h> #include <linux/context_tracking.h>
#include <linux/syscalls.h> #include <linux/syscalls.h>
@ -263,12 +263,12 @@ long do_syscall_trace_enter(struct pt_regs *regs)
flags = read_thread_flags() & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE); flags = read_thread_flags() & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE);
if (flags) { if (flags) {
int rc = tracehook_report_syscall_entry(regs); int rc = ptrace_report_syscall_entry(regs);
if (unlikely(flags & _TIF_SYSCALL_EMU)) { if (unlikely(flags & _TIF_SYSCALL_EMU)) {
/* /*
* A nonzero return code from * A nonzero return code from
* tracehook_report_syscall_entry() tells us to prevent * ptrace_report_syscall_entry() tells us to prevent
* the syscall execution, but we are not going to * the syscall execution, but we are not going to
* execute it anyway. * execute it anyway.
* *
@ -334,7 +334,7 @@ void do_syscall_trace_leave(struct pt_regs *regs)
step = test_thread_flag(TIF_SINGLESTEP); step = test_thread_flag(TIF_SINGLESTEP);
if (step || test_thread_flag(TIF_SYSCALL_TRACE)) if (step || test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall_exit(regs, step); ptrace_report_syscall_exit(regs, step);
} }
void __init pt_regs_check(void); void __init pt_regs_check(void);

View File

@ -17,7 +17,6 @@
#include <linux/regset.h> #include <linux/regset.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/sched/task_stack.h> #include <linux/sched/task_stack.h>
#include <linux/tracehook.h>
#define CREATE_TRACE_POINTS #define CREATE_TRACE_POINTS
#include <trace/events/syscalls.h> #include <trace/events/syscalls.h>
@ -241,7 +240,7 @@ long arch_ptrace(struct task_struct *child, long request,
__visible int do_syscall_trace_enter(struct pt_regs *regs) __visible int do_syscall_trace_enter(struct pt_regs *regs)
{ {
if (test_thread_flag(TIF_SYSCALL_TRACE)) if (test_thread_flag(TIF_SYSCALL_TRACE))
if (tracehook_report_syscall_entry(regs)) if (ptrace_report_syscall_entry(regs))
return -1; return -1;
/* /*
@ -266,7 +265,7 @@ __visible void do_syscall_trace_exit(struct pt_regs *regs)
audit_syscall_exit(regs); audit_syscall_exit(regs);
if (test_thread_flag(TIF_SYSCALL_TRACE)) if (test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall_exit(regs, 0); ptrace_report_syscall_exit(regs, 0);
#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS #ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
if (test_thread_flag(TIF_SYSCALL_TRACEPOINT)) if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))

View File

@ -20,7 +20,6 @@
#include <linux/io.h> #include <linux/io.h>
#include <linux/audit.h> #include <linux/audit.h>
#include <linux/seccomp.h> #include <linux/seccomp.h>
#include <linux/tracehook.h>
#include <linux/elf.h> #include <linux/elf.h>
#include <linux/regset.h> #include <linux/regset.h>
#include <linux/hw_breakpoint.h> #include <linux/hw_breakpoint.h>
@ -456,7 +455,7 @@ long arch_ptrace(struct task_struct *child, long request,
asmlinkage long do_syscall_trace_enter(struct pt_regs *regs) asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
{ {
if (test_thread_flag(TIF_SYSCALL_TRACE) && if (test_thread_flag(TIF_SYSCALL_TRACE) &&
tracehook_report_syscall_entry(regs)) { ptrace_report_syscall_entry(regs)) {
regs->regs[0] = -ENOSYS; regs->regs[0] = -ENOSYS;
return -1; return -1;
} }
@ -484,5 +483,5 @@ asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
step = test_thread_flag(TIF_SINGLESTEP); step = test_thread_flag(TIF_SINGLESTEP);
if (step || test_thread_flag(TIF_SYSCALL_TRACE)) if (step || test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall_exit(regs, step); ptrace_report_syscall_exit(regs, step);
} }

View File

@ -21,7 +21,6 @@
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/regset.h> #include <linux/regset.h>
#include <linux/elf.h> #include <linux/elf.h>
#include <linux/tracehook.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <asm/cacheflush.h> #include <asm/cacheflush.h>
@ -439,9 +438,9 @@ asmlinkage int syscall_trace(struct pt_regs *regs, int syscall_exit_p)
if (test_thread_flag(TIF_SYSCALL_TRACE)) { if (test_thread_flag(TIF_SYSCALL_TRACE)) {
if (syscall_exit_p) if (syscall_exit_p)
tracehook_report_syscall_exit(regs, 0); ptrace_report_syscall_exit(regs, 0);
else else
ret = tracehook_report_syscall_entry(regs); ret = ptrace_report_syscall_entry(regs);
} }
return ret; return ret;

View File

@ -25,7 +25,6 @@
#include <linux/audit.h> #include <linux/audit.h>
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/regset.h> #include <linux/regset.h>
#include <linux/tracehook.h>
#include <trace/syscall.h> #include <trace/syscall.h>
#include <linux/compat.h> #include <linux/compat.h>
#include <linux/elf.h> #include <linux/elf.h>
@ -1095,7 +1094,7 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs)
user_exit(); user_exit();
if (test_thread_flag(TIF_SYSCALL_TRACE)) if (test_thread_flag(TIF_SYSCALL_TRACE))
ret = tracehook_report_syscall_entry(regs); ret = ptrace_report_syscall_entry(regs);
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT))) if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
trace_sys_enter(regs, regs->u_regs[UREG_G1]); trace_sys_enter(regs, regs->u_regs[UREG_G1]);
@ -1118,7 +1117,7 @@ asmlinkage void syscall_trace_leave(struct pt_regs *regs)
trace_sys_exit(regs, regs->u_regs[UREG_I0]); trace_sys_exit(regs, regs->u_regs[UREG_I0]);
if (test_thread_flag(TIF_SYSCALL_TRACE)) if (test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall_exit(regs, 0); ptrace_report_syscall_exit(regs, 0);
if (test_thread_flag(TIF_NOHZ)) if (test_thread_flag(TIF_NOHZ))
user_enter(); user_enter();

View File

@ -6,7 +6,6 @@
#include <linux/audit.h> #include <linux/audit.h>
#include <linux/ptrace.h> #include <linux/ptrace.h>
#include <linux/sched.h> #include <linux/sched.h>
#include <linux/tracehook.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#include <asm/ptrace-abi.h> #include <asm/ptrace-abi.h>
@ -135,7 +134,7 @@ int syscall_trace_enter(struct pt_regs *regs)
if (!test_thread_flag(TIF_SYSCALL_TRACE)) if (!test_thread_flag(TIF_SYSCALL_TRACE))
return 0; return 0;
return tracehook_report_syscall_entry(regs); return ptrace_report_syscall_entry(regs);
} }
void syscall_trace_leave(struct pt_regs *regs) void syscall_trace_leave(struct pt_regs *regs)
@ -151,7 +150,7 @@ void syscall_trace_leave(struct pt_regs *regs)
if (!test_thread_flag(TIF_SYSCALL_TRACE)) if (!test_thread_flag(TIF_SYSCALL_TRACE))
return; return;
tracehook_report_syscall_exit(regs, 0); ptrace_report_syscall_exit(regs, 0);
/* force do_signal() --> is_syscall() */ /* force do_signal() --> is_syscall() */
if (ptraced & PT_PTRACED) if (ptraced & PT_PTRACED)
set_thread_flag(TIF_SIGPENDING); set_thread_flag(TIF_SIGPENDING);

View File

@ -26,7 +26,6 @@
#include <linux/security.h> #include <linux/security.h>
#include <linux/signal.h> #include <linux/signal.h>
#include <linux/smp.h> #include <linux/smp.h>
#include <linux/tracehook.h>
#include <linux/uaccess.h> #include <linux/uaccess.h>
#define CREATE_TRACE_POINTS #define CREATE_TRACE_POINTS
@ -550,7 +549,7 @@ int do_syscall_trace_enter(struct pt_regs *regs)
regs->areg[2] = -ENOSYS; regs->areg[2] = -ENOSYS;
if (test_thread_flag(TIF_SYSCALL_TRACE) && if (test_thread_flag(TIF_SYSCALL_TRACE) &&
tracehook_report_syscall_entry(regs)) { ptrace_report_syscall_entry(regs)) {
regs->areg[2] = -ENOSYS; regs->areg[2] = -ENOSYS;
regs->syscall = NO_SYSCALL; regs->syscall = NO_SYSCALL;
return 0; return 0;
@ -583,5 +582,5 @@ void do_syscall_trace_leave(struct pt_regs *regs)
step = test_thread_flag(TIF_SINGLESTEP); step = test_thread_flag(TIF_SINGLESTEP);
if (step || test_thread_flag(TIF_SYSCALL_TRACE)) if (step || test_thread_flag(TIF_SYSCALL_TRACE))
tracehook_report_syscall_exit(regs, step); ptrace_report_syscall_exit(regs, step);
} }

View File

@ -44,7 +44,7 @@ int syscall_get_nr(struct task_struct *task, struct pt_regs *regs);
* *
* It's only valid to call this when @task is stopped for system * It's only valid to call this when @task is stopped for system
* call exit tracing (due to %SYSCALL_WORK_SYSCALL_TRACE or * call exit tracing (due to %SYSCALL_WORK_SYSCALL_TRACE or
* %SYSCALL_WORK_SYSCALL_AUDIT), after tracehook_report_syscall_entry() * %SYSCALL_WORK_SYSCALL_AUDIT), after ptrace_report_syscall_entry()
* returned nonzero to prevent the system call from taking place. * returned nonzero to prevent the system call from taking place.
* *
* This rolls back the register state in @regs so it's as if the * This rolls back the register state in @regs so it's as if the

View File

@ -3,7 +3,7 @@
#define __LINUX_ENTRYCOMMON_H #define __LINUX_ENTRYCOMMON_H
#include <linux/static_call_types.h> #include <linux/static_call_types.h>
#include <linux/tracehook.h> #include <linux/ptrace.h>
#include <linux/syscalls.h> #include <linux/syscalls.h>
#include <linux/seccomp.h> #include <linux/seccomp.h>
#include <linux/sched.h> #include <linux/sched.h>
@ -95,7 +95,7 @@ static inline __must_check int arch_syscall_enter_tracehook(struct pt_regs *regs
#ifndef arch_syscall_enter_tracehook #ifndef arch_syscall_enter_tracehook
static inline __must_check int arch_syscall_enter_tracehook(struct pt_regs *regs) static inline __must_check int arch_syscall_enter_tracehook(struct pt_regs *regs)
{ {
return tracehook_report_syscall_entry(regs); return ptrace_report_syscall_entry(regs);
} }
#endif #endif
@ -294,7 +294,7 @@ static inline void arch_syscall_exit_tracehook(struct pt_regs *regs, bool step);
#ifndef arch_syscall_exit_tracehook #ifndef arch_syscall_exit_tracehook
static inline void arch_syscall_exit_tracehook(struct pt_regs *regs, bool step) static inline void arch_syscall_exit_tracehook(struct pt_regs *regs, bool step)
{ {
tracehook_report_syscall_exit(regs, step); ptrace_report_syscall_exit(regs, step);
} }
#endif #endif

View File

@ -440,4 +440,55 @@ static inline int ptrace_report_syscall(unsigned long message)
current->ptrace_message = 0; current->ptrace_message = 0;
return fatal_signal_pending(current); return fatal_signal_pending(current);
} }
/**
* ptrace_report_syscall_entry - task is about to attempt a system call
* @regs: user register state of current task
*
* This will be called if %SYSCALL_WORK_SYSCALL_TRACE or
* %SYSCALL_WORK_SYSCALL_EMU have been set, when the current task has just
* entered the kernel for a system call. Full user register state is
* available here. Changing the values in @regs can affect the system
* call number and arguments to be tried. It is safe to block here,
* preventing the system call from beginning.
*
* Returns zero normally, or nonzero if the calling arch code should abort
* the system call. That must prevent normal entry so no system call is
* made. If @task ever returns to user mode after this, its register state
* is unspecified, but should be something harmless like an %ENOSYS error
* return. It should preserve enough information so that syscall_rollback()
* can work (see asm-generic/syscall.h).
*
* Called without locks, just after entering kernel mode.
*/
static inline __must_check int ptrace_report_syscall_entry(
struct pt_regs *regs)
{
return ptrace_report_syscall(PTRACE_EVENTMSG_SYSCALL_ENTRY);
}
/**
* ptrace_report_syscall_exit - task has just finished a system call
* @regs: user register state of current task
* @step: nonzero if simulating single-step or block-step
*
* This will be called if %SYSCALL_WORK_SYSCALL_TRACE has been set, when
* the current task has just finished an attempted system call. Full
* user register state is available here. It is safe to block here,
* preventing signals from being processed.
*
* If @step is nonzero, this report is also in lieu of the normal
* trap that would follow the system call instruction because
* user_enable_block_step() or user_enable_single_step() was used.
* In this case, %SYSCALL_WORK_SYSCALL_TRACE might not be set.
*
* Called without locks, just before checking for pending signals.
*/
static inline void ptrace_report_syscall_exit(struct pt_regs *regs, int step)
{
if (step)
user_single_step_report(regs);
else
ptrace_report_syscall(PTRACE_EVENTMSG_SYSCALL_EXIT);
}
#endif #endif

View File

@ -52,57 +52,6 @@
struct linux_binprm; struct linux_binprm;
/**
* tracehook_report_syscall_entry - task is about to attempt a system call
* @regs: user register state of current task
*
* This will be called if %SYSCALL_WORK_SYSCALL_TRACE or
* %SYSCALL_WORK_SYSCALL_EMU have been set, when the current task has just
* entered the kernel for a system call. Full user register state is
* available here. Changing the values in @regs can affect the system
* call number and arguments to be tried. It is safe to block here,
* preventing the system call from beginning.
*
* Returns zero normally, or nonzero if the calling arch code should abort
* the system call. That must prevent normal entry so no system call is
* made. If @task ever returns to user mode after this, its register state
* is unspecified, but should be something harmless like an %ENOSYS error
* return. It should preserve enough information so that syscall_rollback()
* can work (see asm-generic/syscall.h).
*
* Called without locks, just after entering kernel mode.
*/
static inline __must_check int tracehook_report_syscall_entry(
struct pt_regs *regs)
{
return ptrace_report_syscall(PTRACE_EVENTMSG_SYSCALL_ENTRY);
}
/**
* tracehook_report_syscall_exit - task has just finished a system call
* @regs: user register state of current task
* @step: nonzero if simulating single-step or block-step
*
* This will be called if %SYSCALL_WORK_SYSCALL_TRACE has been set, when
* the current task has just finished an attempted system call. Full
* user register state is available here. It is safe to block here,
* preventing signals from being processed.
*
* If @step is nonzero, this report is also in lieu of the normal
* trap that would follow the system call instruction because
* user_enable_block_step() or user_enable_single_step() was used.
* In this case, %SYSCALL_WORK_SYSCALL_TRACE might not be set.
*
* Called without locks, just before checking for pending signals.
*/
static inline void tracehook_report_syscall_exit(struct pt_regs *regs, int step)
{
if (step)
user_single_step_report(regs);
else
ptrace_report_syscall(PTRACE_EVENTMSG_SYSCALL_EXIT);
}
/** /**
* tracehook_signal_handler - signal handler setup is complete * tracehook_signal_handler - signal handler setup is complete
* @stepping: nonzero if debugger single-step or block-step in use * @stepping: nonzero if debugger single-step or block-step in use

View File

@ -114,7 +114,7 @@ struct ptrace_rseq_configuration {
/* /*
* These values are stored in task->ptrace_message * These values are stored in task->ptrace_message
* by tracehook_report_syscall_* to describe the current syscall-stop. * by ptrace_report_syscall_* to describe the current syscall-stop.
*/ */
#define PTRACE_EVENTMSG_SYSCALL_ENTRY 1 #define PTRACE_EVENTMSG_SYSCALL_ENTRY 1
#define PTRACE_EVENTMSG_SYSCALL_EXIT 2 #define PTRACE_EVENTMSG_SYSCALL_EXIT 2

View File

@ -2,6 +2,7 @@
#include <linux/context_tracking.h> #include <linux/context_tracking.h>
#include <linux/entry-common.h> #include <linux/entry-common.h>
#include <linux/tracehook.h>
#include <linux/highmem.h> #include <linux/highmem.h>
#include <linux/livepatch.h> #include <linux/livepatch.h>
#include <linux/audit.h> #include <linux/audit.h>