mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-23 12:14:10 +08:00
ptrace: Cleanups for v5.18
This set of changes removes tracehook.h, moves modification of all of the ptrace fields inside of siglock to remove races, adds a missing permission check to ptrace.c The removal of tracehook.h is quite significant as it has been a major source of confusion in recent years. Much of that confusion was around task_work and TIF_NOTIFY_SIGNAL (which I have now decoupled making the semantics clearer). For people who don't know tracehook.h is a vestiage of an attempt to implement uprobes like functionality that was never fully merged, and was later superseeded by uprobes when uprobes was merged. For many years now we have been removing what tracehook functionaly a little bit at a time. To the point where now anything left in tracehook.h is some weird strange thing that is difficult to understand. Eric W. Biederman (15): ptrace: Move ptrace_report_syscall into ptrace.h ptrace/arm: Rename tracehook_report_syscall report_syscall ptrace: Create ptrace_report_syscall_{entry,exit} in ptrace.h ptrace: Remove arch_syscall_{enter,exit}_tracehook ptrace: Remove tracehook_signal_handler task_work: Remove unnecessary include from posix_timers.h task_work: Introduce task_work_pending task_work: Call tracehook_notify_signal from get_signal on all architectures task_work: Decouple TIF_NOTIFY_SIGNAL and task_work signal: Move set_notify_signal and clear_notify_signal into sched/signal.h resume_user_mode: Remove #ifdef TIF_NOTIFY_RESUME in set_notify_resume resume_user_mode: Move to resume_user_mode.h tracehook: Remove tracehook.h ptrace: Move setting/clearing ptrace_message into ptrace_stop ptrace: Return the signal to continue with from ptrace_stop Jann Horn (1): ptrace: Check PTRACE_O_SUSPEND_SECCOMP permission on PTRACE_SEIZE Yang Li (1): ptrace: Remove duplicated include in ptrace.c MAINTAINERS | 1 - arch/Kconfig | 5 +- arch/alpha/kernel/ptrace.c | 5 +- arch/alpha/kernel/signal.c | 4 +- arch/arc/kernel/ptrace.c | 5 +- arch/arc/kernel/signal.c | 4 +- arch/arm/kernel/ptrace.c | 12 +- arch/arm/kernel/signal.c | 4 +- arch/arm64/kernel/ptrace.c | 14 +-- arch/arm64/kernel/signal.c | 4 +- arch/csky/kernel/ptrace.c | 5 +- arch/csky/kernel/signal.c | 4 +- arch/h8300/kernel/ptrace.c | 5 +- arch/h8300/kernel/signal.c | 4 +- arch/hexagon/kernel/process.c | 4 +- arch/hexagon/kernel/signal.c | 1 - arch/hexagon/kernel/traps.c | 6 +- arch/ia64/kernel/process.c | 4 +- arch/ia64/kernel/ptrace.c | 6 +- arch/ia64/kernel/signal.c | 1 - arch/m68k/kernel/ptrace.c | 5 +- arch/m68k/kernel/signal.c | 4 +- arch/microblaze/kernel/ptrace.c | 5 +- arch/microblaze/kernel/signal.c | 4 +- arch/mips/kernel/ptrace.c | 5 +- arch/mips/kernel/signal.c | 4 +- arch/nds32/include/asm/syscall.h | 2 +- arch/nds32/kernel/ptrace.c | 5 +- arch/nds32/kernel/signal.c | 4 +- arch/nios2/kernel/ptrace.c | 5 +- arch/nios2/kernel/signal.c | 4 +- arch/openrisc/kernel/ptrace.c | 5 +- arch/openrisc/kernel/signal.c | 4 +- arch/parisc/kernel/ptrace.c | 7 +- arch/parisc/kernel/signal.c | 4 +- arch/powerpc/kernel/ptrace/ptrace.c | 8 +- arch/powerpc/kernel/signal.c | 4 +- arch/riscv/kernel/ptrace.c | 5 +- arch/riscv/kernel/signal.c | 4 +- arch/s390/include/asm/entry-common.h | 1 - arch/s390/kernel/ptrace.c | 1 - arch/s390/kernel/signal.c | 5 +- arch/sh/kernel/ptrace_32.c | 5 +- arch/sh/kernel/signal_32.c | 4 +- arch/sparc/kernel/ptrace_32.c | 5 +- arch/sparc/kernel/ptrace_64.c | 5 +- arch/sparc/kernel/signal32.c | 1 - arch/sparc/kernel/signal_32.c | 4 +- arch/sparc/kernel/signal_64.c | 4 +- arch/um/kernel/process.c | 4 +- arch/um/kernel/ptrace.c | 5 +- arch/x86/kernel/ptrace.c | 1 - arch/x86/kernel/signal.c | 5 +- arch/x86/mm/tlb.c | 1 + arch/xtensa/kernel/ptrace.c | 5 +- arch/xtensa/kernel/signal.c | 4 +- block/blk-cgroup.c | 2 +- fs/coredump.c | 1 - fs/exec.c | 1 - fs/io-wq.c | 6 +- fs/io_uring.c | 11 +- fs/proc/array.c | 1 - fs/proc/base.c | 1 - include/asm-generic/syscall.h | 2 +- include/linux/entry-common.h | 47 +------- include/linux/entry-kvm.h | 2 +- include/linux/posix-timers.h | 1 - include/linux/ptrace.h | 81 ++++++++++++- include/linux/resume_user_mode.h | 64 ++++++++++ include/linux/sched/signal.h | 17 +++ include/linux/task_work.h | 5 + include/linux/tracehook.h | 226 ----------------------------------- include/uapi/linux/ptrace.h | 2 +- kernel/entry/common.c | 19 +-- kernel/entry/kvm.c | 9 +- kernel/exit.c | 3 +- kernel/livepatch/transition.c | 1 - kernel/ptrace.c | 47 +++++--- kernel/seccomp.c | 1 - kernel/signal.c | 62 +++++----- kernel/task_work.c | 4 +- kernel/time/posix-cpu-timers.c | 1 + mm/memcontrol.c | 2 +- security/apparmor/domain.c | 1 - security/selinux/hooks.c | 1 - 85 files changed, 372 insertions(+), 495 deletions(-) Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com> -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEgjlraLDcwBA2B+6cC/v6Eiajj0AFAmJCQkoACgkQC/v6Eiaj j0DCWQ/5AZVFU+hX32obUNCLackHTwgcCtSOs3JNBmNA/zL/htPiYYG0ghkvtlDR Dw5J5DnxC6P7PVAdAqrpvx2uX2FebHYU0bRlyLx8LYUEP5dhyNicxX9jA882Z+vw Ud0Ue9EojwGWS76dC9YoKUj3slThMATbhA2r4GVEoof8fSNJaBxQIqath44t0FwU DinWa+tIOvZANGBZr6CUUINNIgqBIZCH/R4h6ArBhMlJpuQ5Ufk2kAaiWFwZCkX4 0LuuAwbKsCKkF8eap5I2KrIg/7zZVgxAg9O3cHOzzm8OPbKzRnNnQClcDe8perqp S6e/f3MgpE+eavd1EiLxevZ660cJChnmikXVVh8ZYYoefaMKGqBaBSsB38bNcLjY 3+f2dB+TNBFRnZs1aCujK3tWBT9QyjZDKtCBfzxDNWBpXGLhHH6j6lA5Lj+Cef5K /HNHFb+FuqedlFZh5m1Y+piFQ70hTgCa2u8b+FSOubI2hW9Zd+WzINV0ANaZ2LvZ 4YGtcyDNk1q1+c87lxP9xMRl/xi6rNg+B9T2MCo4IUnHgpSVP6VEB3osgUmrrrN0 eQlUI154G/AaDlqXLgmn1xhRmlPGfmenkxpok1AuzxvNJsfLKnpEwQSc13g3oiZr disZQxNY0kBO2Nv3G323Z6PLinhbiIIFez6cJzK5v0YJ2WtO3pY= =uEro -----END PGP SIGNATURE----- Merge tag 'ptrace-cleanups-for-v5.18' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace Pull ptrace cleanups from Eric Biederman: "This set of changes removes tracehook.h, moves modification of all of the ptrace fields inside of siglock to remove races, adds a missing permission check to ptrace.c The removal of tracehook.h is quite significant as it has been a major source of confusion in recent years. Much of that confusion was around task_work and TIF_NOTIFY_SIGNAL (which I have now decoupled making the semantics clearer). For people who don't know tracehook.h is a vestiage of an attempt to implement uprobes like functionality that was never fully merged, and was later superseeded by uprobes when uprobes was merged. For many years now we have been removing what tracehook functionaly a little bit at a time. To the point where anything left in tracehook.h was some weird strange thing that was difficult to understand" * tag 'ptrace-cleanups-for-v5.18' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiederm/user-namespace: ptrace: Remove duplicated include in ptrace.c ptrace: Check PTRACE_O_SUSPEND_SECCOMP permission on PTRACE_SEIZE ptrace: Return the signal to continue with from ptrace_stop ptrace: Move setting/clearing ptrace_message into ptrace_stop tracehook: Remove tracehook.h resume_user_mode: Move to resume_user_mode.h resume_user_mode: Remove #ifdef TIF_NOTIFY_RESUME in set_notify_resume signal: Move set_notify_signal and clear_notify_signal into sched/signal.h task_work: Decouple TIF_NOTIFY_SIGNAL and task_work task_work: Call tracehook_notify_signal from get_signal on all architectures task_work: Introduce task_work_pending task_work: Remove unnecessary include from posix_timers.h ptrace: Remove tracehook_signal_handler ptrace: Remove arch_syscall_{enter,exit}_tracehook ptrace: Create ptrace_report_syscall_{entry,exit} in ptrace.h ptrace/arm: Rename tracehook_report_syscall report_syscall ptrace: Move ptrace_report_syscall into ptrace.h
This commit is contained in:
commit
1930a6e739
@ -15930,7 +15930,6 @@ F: arch/*/ptrace*.c
|
||||
F: include/asm-generic/syscall.h
|
||||
F: include/linux/ptrace.h
|
||||
F: include/linux/regset.h
|
||||
F: include/linux/tracehook.h
|
||||
F: include/uapi/linux/ptrace.h
|
||||
F: include/uapi/linux/ptrace.h
|
||||
F: kernel/ptrace.c
|
||||
|
@ -217,9 +217,8 @@ config TRACE_IRQFLAGS_SUPPORT
|
||||
# asm/syscall.h supplying asm-generic/syscall.h interface
|
||||
# linux/regset.h user_regset interfaces
|
||||
# CORE_DUMP_USE_REGSET #define'd in linux/elf.h
|
||||
# TIF_SYSCALL_TRACE calls tracehook_report_syscall_{entry,exit}
|
||||
# TIF_NOTIFY_RESUME calls tracehook_notify_resume()
|
||||
# signal delivery calls tracehook_signal_handler()
|
||||
# TIF_SYSCALL_TRACE calls ptrace_report_syscall_{entry,exit}
|
||||
# TIF_NOTIFY_RESUME calls resume_user_mode_work()
|
||||
#
|
||||
config HAVE_ARCH_TRACEHOOK
|
||||
bool
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include <linux/user.h>
|
||||
#include <linux/security.h>
|
||||
#include <linux/signal.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/audit.h>
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
@ -323,7 +322,7 @@ asmlinkage unsigned long syscall_trace_enter(void)
|
||||
unsigned long ret = 0;
|
||||
struct pt_regs *regs = current_pt_regs();
|
||||
if (test_thread_flag(TIF_SYSCALL_TRACE) &&
|
||||
tracehook_report_syscall_entry(current_pt_regs()))
|
||||
ptrace_report_syscall_entry(current_pt_regs()))
|
||||
ret = -1UL;
|
||||
audit_syscall_entry(regs->r0, regs->r16, regs->r17, regs->r18, regs->r19);
|
||||
return ret ?: current_pt_regs()->r0;
|
||||
@ -334,5 +333,5 @@ syscall_trace_leave(void)
|
||||
{
|
||||
audit_syscall_exit(current_pt_regs());
|
||||
if (test_thread_flag(TIF_SYSCALL_TRACE))
|
||||
tracehook_report_syscall_exit(current_pt_regs(), 0);
|
||||
ptrace_report_syscall_exit(current_pt_regs(), 0);
|
||||
}
|
||||
|
@ -22,7 +22,7 @@
|
||||
#include <linux/binfmts.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/resume_user_mode.h>
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/sigcontext.h>
|
||||
@ -531,7 +531,7 @@ do_work_pending(struct pt_regs *regs, unsigned long thread_flags,
|
||||
do_signal(regs, r0, r19);
|
||||
r0 = 0;
|
||||
} else {
|
||||
tracehook_notify_resume(regs);
|
||||
resume_user_mode_work(regs);
|
||||
}
|
||||
}
|
||||
local_irq_disable();
|
||||
|
@ -4,7 +4,6 @@
|
||||
*/
|
||||
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/sched/task_stack.h>
|
||||
#include <linux/regset.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)
|
||||
{
|
||||
if (tracehook_report_syscall_entry(regs))
|
||||
if (ptrace_report_syscall_entry(regs))
|
||||
return ULONG_MAX;
|
||||
|
||||
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)
|
||||
{
|
||||
tracehook_report_syscall_exit(regs, 0);
|
||||
ptrace_report_syscall_exit(regs, 0);
|
||||
}
|
||||
|
@ -49,7 +49,7 @@
|
||||
#include <linux/personality.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/resume_user_mode.h>
|
||||
#include <linux/sched/task_stack.h>
|
||||
|
||||
#include <asm/ucontext.h>
|
||||
@ -438,5 +438,5 @@ void do_notify_resume(struct pt_regs *regs)
|
||||
* user mode
|
||||
*/
|
||||
if (test_thread_flag(TIF_NOTIFY_RESUME))
|
||||
tracehook_notify_resume(regs);
|
||||
resume_user_mode_work(regs);
|
||||
}
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include <linux/hw_breakpoint.h>
|
||||
#include <linux/regset.h>
|
||||
#include <linux/audit.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/unistd.h>
|
||||
|
||||
#include <asm/syscall.h>
|
||||
@ -831,8 +830,7 @@ enum ptrace_syscall_dir {
|
||||
PTRACE_SYSCALL_EXIT,
|
||||
};
|
||||
|
||||
static void tracehook_report_syscall(struct pt_regs *regs,
|
||||
enum ptrace_syscall_dir dir)
|
||||
static void report_syscall(struct pt_regs *regs, enum ptrace_syscall_dir dir)
|
||||
{
|
||||
unsigned long ip;
|
||||
|
||||
@ -844,8 +842,8 @@ static void tracehook_report_syscall(struct pt_regs *regs,
|
||||
regs->ARM_ip = dir;
|
||||
|
||||
if (dir == PTRACE_SYSCALL_EXIT)
|
||||
tracehook_report_syscall_exit(regs, 0);
|
||||
else if (tracehook_report_syscall_entry(regs))
|
||||
ptrace_report_syscall_exit(regs, 0);
|
||||
else if (ptrace_report_syscall_entry(regs))
|
||||
current_thread_info()->abi_syscall = -1;
|
||||
|
||||
regs->ARM_ip = ip;
|
||||
@ -856,7 +854,7 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs)
|
||||
int scno;
|
||||
|
||||
if (test_thread_flag(TIF_SYSCALL_TRACE))
|
||||
tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
|
||||
report_syscall(regs, PTRACE_SYSCALL_ENTER);
|
||||
|
||||
/* Do seccomp after ptrace; syscall may have changed. */
|
||||
#ifdef CONFIG_HAVE_ARCH_SECCOMP_FILTER
|
||||
@ -897,5 +895,5 @@ asmlinkage void syscall_trace_exit(struct pt_regs *regs)
|
||||
trace_sys_exit(regs, regs_return_value(regs));
|
||||
|
||||
if (test_thread_flag(TIF_SYSCALL_TRACE))
|
||||
tracehook_report_syscall(regs, PTRACE_SYSCALL_EXIT);
|
||||
report_syscall(regs, PTRACE_SYSCALL_EXIT);
|
||||
}
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include <linux/signal.h>
|
||||
#include <linux/personality.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/resume_user_mode.h>
|
||||
#include <linux/uprobes.h>
|
||||
#include <linux/syscalls.h>
|
||||
|
||||
@ -627,7 +627,7 @@ do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall)
|
||||
} else if (thread_flags & _TIF_UPROBE) {
|
||||
uprobe_notify_resume(regs);
|
||||
} else {
|
||||
tracehook_notify_resume(regs);
|
||||
resume_user_mode_work(regs);
|
||||
}
|
||||
}
|
||||
local_irq_disable();
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include <linux/perf_event.h>
|
||||
#include <linux/hw_breakpoint.h>
|
||||
#include <linux/regset.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/elf.h>
|
||||
|
||||
#include <asm/compat.h>
|
||||
@ -1792,8 +1791,7 @@ enum ptrace_syscall_dir {
|
||||
PTRACE_SYSCALL_EXIT,
|
||||
};
|
||||
|
||||
static void tracehook_report_syscall(struct pt_regs *regs,
|
||||
enum ptrace_syscall_dir dir)
|
||||
static void report_syscall(struct pt_regs *regs, enum ptrace_syscall_dir dir)
|
||||
{
|
||||
int regno;
|
||||
unsigned long saved_reg;
|
||||
@ -1819,11 +1817,11 @@ static void tracehook_report_syscall(struct pt_regs *regs,
|
||||
regs->regs[regno] = dir;
|
||||
|
||||
if (dir == PTRACE_SYSCALL_ENTER) {
|
||||
if (tracehook_report_syscall_entry(regs))
|
||||
if (ptrace_report_syscall_entry(regs))
|
||||
forget_syscall(regs);
|
||||
regs->regs[regno] = saved_reg;
|
||||
} else if (!test_thread_flag(TIF_SINGLESTEP)) {
|
||||
tracehook_report_syscall_exit(regs, 0);
|
||||
ptrace_report_syscall_exit(regs, 0);
|
||||
regs->regs[regno] = saved_reg;
|
||||
} else {
|
||||
regs->regs[regno] = saved_reg;
|
||||
@ -1833,7 +1831,7 @@ static void tracehook_report_syscall(struct pt_regs *regs,
|
||||
* tracer modifications to the registers may have rewound the
|
||||
* state machine.
|
||||
*/
|
||||
tracehook_report_syscall_exit(regs, 1);
|
||||
ptrace_report_syscall_exit(regs, 1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1842,7 +1840,7 @@ int syscall_trace_enter(struct pt_regs *regs)
|
||||
unsigned long flags = read_thread_flags();
|
||||
|
||||
if (flags & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE)) {
|
||||
tracehook_report_syscall(regs, PTRACE_SYSCALL_ENTER);
|
||||
report_syscall(regs, PTRACE_SYSCALL_ENTER);
|
||||
if (flags & _TIF_SYSCALL_EMU)
|
||||
return NO_SYSCALL;
|
||||
}
|
||||
@ -1870,7 +1868,7 @@ void syscall_trace_exit(struct pt_regs *regs)
|
||||
trace_sys_exit(regs, syscall_get_return_value(current, regs));
|
||||
|
||||
if (flags & (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP))
|
||||
tracehook_report_syscall(regs, PTRACE_SYSCALL_EXIT);
|
||||
report_syscall(regs, PTRACE_SYSCALL_EXIT);
|
||||
|
||||
rseq_syscall(regs);
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/sizes.h>
|
||||
#include <linux/string.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/resume_user_mode.h>
|
||||
#include <linux/ratelimit.h>
|
||||
#include <linux/syscalls.h>
|
||||
|
||||
@ -942,7 +942,7 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_flags)
|
||||
do_signal(regs);
|
||||
|
||||
if (thread_flags & _TIF_NOTIFY_RESUME)
|
||||
tracehook_notify_resume(regs);
|
||||
resume_user_mode_work(regs);
|
||||
|
||||
if (thread_flags & _TIF_FOREIGN_FPSTATE)
|
||||
fpsimd_restore_current_state();
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include <linux/sched/task_stack.h>
|
||||
#include <linux/signal.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/uaccess.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)
|
||||
{
|
||||
if (test_thread_flag(TIF_SYSCALL_TRACE))
|
||||
if (tracehook_report_syscall_entry(regs))
|
||||
if (ptrace_report_syscall_entry(regs))
|
||||
return -1;
|
||||
|
||||
if (secure_computing() == -1)
|
||||
@ -339,7 +338,7 @@ asmlinkage void syscall_trace_exit(struct pt_regs *regs)
|
||||
audit_syscall_exit(regs);
|
||||
|
||||
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))
|
||||
trace_sys_exit(regs, syscall_get_return_value(current, regs));
|
||||
|
@ -3,7 +3,7 @@
|
||||
#include <linux/signal.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/resume_user_mode.h>
|
||||
|
||||
#include <asm/traps.h>
|
||||
#include <asm/ucontext.h>
|
||||
@ -265,5 +265,5 @@ asmlinkage void do_notify_resume(struct pt_regs *regs,
|
||||
do_signal(regs);
|
||||
|
||||
if (thread_info_flags & _TIF_NOTIFY_RESUME)
|
||||
tracehook_notify_resume(regs);
|
||||
resume_user_mode_work(regs);
|
||||
}
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include <linux/errno.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/audit.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/regset.h>
|
||||
#include <linux/elf.h>
|
||||
|
||||
@ -174,7 +173,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
|
||||
long ret = 0;
|
||||
|
||||
if (test_thread_flag(TIF_SYSCALL_TRACE) &&
|
||||
tracehook_report_syscall_entry(regs))
|
||||
ptrace_report_syscall_entry(regs))
|
||||
/*
|
||||
* Tracing decided this syscall should not happen.
|
||||
* 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);
|
||||
if (step || test_thread_flag(TIF_SYSCALL_TRACE))
|
||||
tracehook_report_syscall_exit(regs, step);
|
||||
ptrace_report_syscall_exit(regs, step);
|
||||
}
|
||||
|
@ -39,7 +39,7 @@
|
||||
#include <linux/personality.h>
|
||||
#include <linux/tty.h>
|
||||
#include <linux/binfmts.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/resume_user_mode.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <linux/uaccess.h>
|
||||
@ -283,5 +283,5 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags)
|
||||
do_signal(regs);
|
||||
|
||||
if (thread_info_flags & _TIF_NOTIFY_RESUME)
|
||||
tracehook_notify_resume(regs);
|
||||
resume_user_mode_work(regs);
|
||||
}
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include <linux/tick.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/resume_user_mode.h>
|
||||
|
||||
/*
|
||||
* Program thread launch. Often defined as a macro in processor.h,
|
||||
@ -177,7 +177,7 @@ int do_work_pending(struct pt_regs *regs, u32 thread_info_flags)
|
||||
}
|
||||
|
||||
if (thread_info_flags & _TIF_NOTIFY_RESUME) {
|
||||
tracehook_notify_resume(regs);
|
||||
resume_user_mode_work(regs);
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -7,7 +7,6 @@
|
||||
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/sched/task_stack.h>
|
||||
|
||||
#include <asm/registers.h>
|
||||
|
@ -14,7 +14,7 @@
|
||||
#include <linux/kdebug.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/signal.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <asm/traps.h>
|
||||
#include <asm/vm_fault.h>
|
||||
#include <asm/syscall.h>
|
||||
@ -348,7 +348,7 @@ void do_trap0(struct pt_regs *regs)
|
||||
|
||||
/* allow strace to catch syscall args */
|
||||
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACE) &&
|
||||
tracehook_report_syscall_entry(regs)))
|
||||
ptrace_report_syscall_entry(regs)))
|
||||
return; /* return -ENOSYS somewhere? */
|
||||
|
||||
/* 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 */
|
||||
if (unlikely(test_thread_flag(TIF_SYSCALL_TRACE)))
|
||||
tracehook_report_syscall_exit(regs, 0);
|
||||
ptrace_report_syscall_exit(regs, 0);
|
||||
|
||||
break;
|
||||
case TRAP_DEBUG:
|
||||
|
@ -32,7 +32,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/kdebug.h>
|
||||
#include <linux/utsname.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/resume_user_mode.h>
|
||||
#include <linux/rcupdate.h>
|
||||
|
||||
#include <asm/cpu.h>
|
||||
@ -179,7 +179,7 @@ do_notify_resume_user(sigset_t *unused, struct sigscratch *scr, long in_syscall)
|
||||
|
||||
if (test_thread_flag(TIF_NOTIFY_RESUME)) {
|
||||
local_irq_enable(); /* force interrupt enable */
|
||||
tracehook_notify_resume(&scr->pt);
|
||||
resume_user_mode_work(&scr->pt);
|
||||
}
|
||||
|
||||
/* copy user rbs to kernel rbs */
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include <linux/signal.h>
|
||||
#include <linux/regset.h>
|
||||
#include <linux/elf.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/resume_user_mode.h>
|
||||
|
||||
#include <asm/processor.h>
|
||||
#include <asm/ptrace_offsets.h>
|
||||
@ -1217,7 +1217,7 @@ syscall_trace_enter (long arg0, long arg1, long arg2, long arg3,
|
||||
struct pt_regs regs)
|
||||
{
|
||||
if (test_thread_flag(TIF_SYSCALL_TRACE))
|
||||
if (tracehook_report_syscall_entry(®s))
|
||||
if (ptrace_report_syscall_entry(®s))
|
||||
return -ENOSYS;
|
||||
|
||||
/* 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);
|
||||
if (step || test_thread_flag(TIF_SYSCALL_TRACE))
|
||||
tracehook_report_syscall_exit(®s, step);
|
||||
ptrace_report_syscall_exit(®s, step);
|
||||
|
||||
/* copy user rbs to kernel rbs */
|
||||
if (test_thread_flag(TIF_RESTORE_RSE))
|
||||
|
@ -12,7 +12,6 @@
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/signal.h>
|
||||
#include <linux/smp.h>
|
||||
|
@ -19,7 +19,6 @@
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/user.h>
|
||||
#include <linux/signal.h>
|
||||
#include <linux/tracehook.h>
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/page.h>
|
||||
@ -282,13 +281,13 @@ asmlinkage int syscall_trace_enter(void)
|
||||
int ret = 0;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
asmlinkage void syscall_trace_leave(void)
|
||||
{
|
||||
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 */
|
||||
|
@ -43,7 +43,7 @@
|
||||
#include <linux/tty.h>
|
||||
#include <linux/binfmts.h>
|
||||
#include <linux/extable.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/resume_user_mode.h>
|
||||
|
||||
#include <asm/setup.h>
|
||||
#include <linux/uaccess.h>
|
||||
@ -1109,5 +1109,5 @@ void do_notify_resume(struct pt_regs *regs)
|
||||
do_signal(regs);
|
||||
|
||||
if (test_thread_flag(TIF_NOTIFY_RESUME))
|
||||
tracehook_notify_resume(regs);
|
||||
resume_user_mode_work(regs);
|
||||
}
|
||||
|
@ -33,7 +33,6 @@
|
||||
#include <linux/elf.h>
|
||||
#include <linux/audit.h>
|
||||
#include <linux/seccomp.h>
|
||||
#include <linux/tracehook.h>
|
||||
|
||||
#include <linux/errno.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);
|
||||
|
||||
if (test_thread_flag(TIF_SYSCALL_TRACE) &&
|
||||
tracehook_report_syscall_entry(regs))
|
||||
ptrace_report_syscall_entry(regs))
|
||||
/*
|
||||
* Tracing decided this syscall should not happen.
|
||||
* 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);
|
||||
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)
|
||||
|
@ -31,7 +31,7 @@
|
||||
#include <linux/personality.h>
|
||||
#include <linux/percpu.h>
|
||||
#include <linux/linkage.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/resume_user_mode.h>
|
||||
#include <asm/entry.h>
|
||||
#include <asm/ucontext.h>
|
||||
#include <linux/uaccess.h>
|
||||
@ -311,5 +311,5 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, int in_syscall)
|
||||
do_signal(regs, in_syscall);
|
||||
|
||||
if (test_thread_flag(TIF_NOTIFY_RESUME))
|
||||
tracehook_notify_resume(regs);
|
||||
resume_user_mode_work(regs);
|
||||
}
|
||||
|
@ -27,7 +27,6 @@
|
||||
#include <linux/smp.h>
|
||||
#include <linux/security.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/audit.h>
|
||||
#include <linux/seccomp.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;
|
||||
|
||||
if (test_thread_flag(TIF_SYSCALL_TRACE)) {
|
||||
if (tracehook_report_syscall_entry(regs))
|
||||
if (ptrace_report_syscall_entry(regs))
|
||||
return -1;
|
||||
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));
|
||||
|
||||
if (test_thread_flag(TIF_SYSCALL_TRACE))
|
||||
tracehook_report_syscall_exit(regs, 0);
|
||||
ptrace_report_syscall_exit(regs, 0);
|
||||
|
||||
user_enter();
|
||||
}
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include <linux/compiler.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/resume_user_mode.h>
|
||||
|
||||
#include <asm/abi.h>
|
||||
#include <asm/asm.h>
|
||||
@ -915,7 +915,7 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, void *unused,
|
||||
do_signal(regs);
|
||||
|
||||
if (thread_info_flags & _TIF_NOTIFY_RESUME)
|
||||
tracehook_notify_resume(regs);
|
||||
resume_user_mode_work(regs);
|
||||
|
||||
user_enter();
|
||||
}
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include <linux/regset.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/sched/task_stack.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/user.h>
|
||||
|
||||
@ -134,7 +133,7 @@ asmlinkage int do_syscall_trace_enter(void)
|
||||
int ret = 0;
|
||||
|
||||
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;
|
||||
}
|
||||
@ -142,5 +141,5 @@ asmlinkage int do_syscall_trace_enter(void)
|
||||
asmlinkage void do_syscall_trace_exit(void)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/unistd.h>
|
||||
#include <linux/personality.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/resume_user_mode.h>
|
||||
|
||||
#include <asm/ucontext.h>
|
||||
#include <asm/cacheflush.h>
|
||||
@ -321,7 +321,7 @@ asmlinkage int do_notify_resume(struct pt_regs *regs)
|
||||
return restart;
|
||||
}
|
||||
} else if (test_thread_flag(TIF_NOTIFY_RESUME))
|
||||
tracehook_notify_resume(regs);
|
||||
resume_user_mode_work(regs);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -22,7 +22,6 @@
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/audit.h>
|
||||
#include <linux/regset.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/elf.h>
|
||||
|
||||
#include <asm/thread_info.h>
|
||||
@ -159,7 +158,7 @@ asmlinkage long do_syscall_trace_enter(struct pt_regs *regs)
|
||||
long ret = 0;
|
||||
|
||||
if (test_thread_flag(TIF_SYSCALL_TRACE) &&
|
||||
tracehook_report_syscall_entry(regs))
|
||||
ptrace_report_syscall_entry(regs))
|
||||
/*
|
||||
* Tracing decided this syscall should not happen.
|
||||
* 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);
|
||||
if (step || test_thread_flag(TIF_SYSCALL_TRACE))
|
||||
tracehook_report_syscall_exit(regs, step);
|
||||
ptrace_report_syscall_exit(regs, step);
|
||||
}
|
||||
|
@ -21,7 +21,7 @@
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/unistd.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/resume_user_mode.h>
|
||||
|
||||
#include <asm/processor.h>
|
||||
#include <asm/syscall.h>
|
||||
@ -309,7 +309,7 @@ do_work_pending(struct pt_regs *regs, unsigned int thread_flags, int syscall)
|
||||
}
|
||||
syscall = 0;
|
||||
} else {
|
||||
tracehook_notify_resume(regs);
|
||||
resume_user_mode_work(regs);
|
||||
}
|
||||
}
|
||||
local_irq_disable();
|
||||
|
@ -15,7 +15,6 @@
|
||||
#include <linux/elf.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/user.h>
|
||||
#include <linux/personality.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)
|
||||
{
|
||||
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
|
||||
@ -327,7 +326,7 @@ long do_syscall_trace_enter(struct pt_regs *regs)
|
||||
if (rc) {
|
||||
/*
|
||||
* A nonzero return code from
|
||||
* tracehook_report_syscall_entry() tells us
|
||||
* ptrace_report_syscall_entry() tells us
|
||||
* to prevent the syscall execution. Skip
|
||||
* the syscall call and the syscall restart handling.
|
||||
*
|
||||
@ -381,7 +380,7 @@ void do_syscall_trace_exit(struct pt_regs *regs)
|
||||
#endif
|
||||
|
||||
if (stepping || test_thread_flag(TIF_SYSCALL_TRACE))
|
||||
tracehook_report_syscall_exit(regs, stepping);
|
||||
ptrace_report_syscall_exit(regs, stepping);
|
||||
}
|
||||
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include <linux/errno.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/resume_user_mode.h>
|
||||
#include <linux/unistd.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/compat.h>
|
||||
@ -585,5 +585,5 @@ void do_notify_resume(struct pt_regs *regs, long in_syscall)
|
||||
do_signal(regs, in_syscall);
|
||||
|
||||
if (test_thread_flag(TIF_NOTIFY_RESUME))
|
||||
tracehook_notify_resume(regs);
|
||||
resume_user_mode_work(regs);
|
||||
}
|
||||
|
@ -16,7 +16,7 @@
|
||||
*/
|
||||
|
||||
#include <linux/regset.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/audit.h>
|
||||
#include <linux/context_tracking.h>
|
||||
#include <linux/syscalls.h>
|
||||
@ -262,12 +262,12 @@ long do_syscall_trace_enter(struct pt_regs *regs)
|
||||
flags = read_thread_flags() & (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE);
|
||||
|
||||
if (flags) {
|
||||
int rc = tracehook_report_syscall_entry(regs);
|
||||
int rc = ptrace_report_syscall_entry(regs);
|
||||
|
||||
if (unlikely(flags & _TIF_SYSCALL_EMU)) {
|
||||
/*
|
||||
* 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
|
||||
* execute it anyway.
|
||||
*
|
||||
@ -333,7 +333,7 @@ void do_syscall_trace_leave(struct pt_regs *regs)
|
||||
|
||||
step = test_thread_flag(TIF_SINGLESTEP);
|
||||
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);
|
||||
|
@ -9,7 +9,7 @@
|
||||
* this archive for more details.
|
||||
*/
|
||||
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/resume_user_mode.h>
|
||||
#include <linux/signal.h>
|
||||
#include <linux/uprobes.h>
|
||||
#include <linux/key.h>
|
||||
@ -294,7 +294,7 @@ void do_notify_resume(struct pt_regs *regs, unsigned long thread_info_flags)
|
||||
}
|
||||
|
||||
if (thread_info_flags & _TIF_NOTIFY_RESUME)
|
||||
tracehook_notify_resume(regs);
|
||||
resume_user_mode_work(regs);
|
||||
}
|
||||
|
||||
static unsigned long get_tm_stackpointer(struct task_struct *tsk)
|
||||
|
@ -17,7 +17,6 @@
|
||||
#include <linux/regset.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/sched/task_stack.h>
|
||||
#include <linux/tracehook.h>
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
#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)
|
||||
{
|
||||
if (test_thread_flag(TIF_SYSCALL_TRACE))
|
||||
if (tracehook_report_syscall_entry(regs))
|
||||
if (ptrace_report_syscall_entry(regs))
|
||||
return -1;
|
||||
|
||||
/*
|
||||
@ -266,7 +265,7 @@ __visible void do_syscall_trace_exit(struct pt_regs *regs)
|
||||
audit_syscall_exit(regs);
|
||||
|
||||
if (test_thread_flag(TIF_SYSCALL_TRACE))
|
||||
tracehook_report_syscall_exit(regs, 0);
|
||||
ptrace_report_syscall_exit(regs, 0);
|
||||
|
||||
#ifdef CONFIG_HAVE_SYSCALL_TRACEPOINTS
|
||||
if (test_thread_flag(TIF_SYSCALL_TRACEPOINT))
|
||||
|
@ -9,7 +9,7 @@
|
||||
#include <linux/signal.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/resume_user_mode.h>
|
||||
#include <linux/linkage.h>
|
||||
|
||||
#include <asm/ucontext.h>
|
||||
@ -319,5 +319,5 @@ asmlinkage __visible void do_notify_resume(struct pt_regs *regs,
|
||||
do_signal(regs);
|
||||
|
||||
if (thread_info_flags & _TIF_NOTIFY_RESUME)
|
||||
tracehook_notify_resume(regs);
|
||||
resume_user_mode_work(regs);
|
||||
}
|
||||
|
@ -5,7 +5,6 @@
|
||||
#include <linux/sched.h>
|
||||
#include <linux/audit.h>
|
||||
#include <linux/randomize_kstack.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/processor.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/timex.h>
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include <linux/signal.h>
|
||||
#include <linux/elf.h>
|
||||
#include <linux/regset.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/seccomp.h>
|
||||
#include <linux/compat.h>
|
||||
#include <trace/syscall.h>
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include <linux/tty.h>
|
||||
#include <linux/personality.h>
|
||||
#include <linux/binfmts.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/compat.h>
|
||||
#include <asm/ucontext.h>
|
||||
@ -453,7 +452,7 @@ static void handle_signal(struct ksignal *ksig, sigset_t *oldset,
|
||||
* stack-frames in one go after that.
|
||||
*/
|
||||
|
||||
void arch_do_signal_or_restart(struct pt_regs *regs, bool has_signal)
|
||||
void arch_do_signal_or_restart(struct pt_regs *regs)
|
||||
{
|
||||
struct ksignal ksig;
|
||||
sigset_t *oldset = sigmask_to_save();
|
||||
@ -466,7 +465,7 @@ void arch_do_signal_or_restart(struct pt_regs *regs, bool has_signal)
|
||||
current->thread.system_call =
|
||||
test_pt_regs_flag(regs, PIF_SYSCALL) ? regs->int_code : 0;
|
||||
|
||||
if (has_signal && get_signal(&ksig)) {
|
||||
if (get_signal(&ksig)) {
|
||||
/* Whee! Actually deliver the signal. */
|
||||
if (current->thread.system_call) {
|
||||
regs->int_code = current->thread.system_call;
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include <linux/io.h>
|
||||
#include <linux/audit.h>
|
||||
#include <linux/seccomp.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/elf.h>
|
||||
#include <linux/regset.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)
|
||||
{
|
||||
if (test_thread_flag(TIF_SYSCALL_TRACE) &&
|
||||
tracehook_report_syscall_entry(regs)) {
|
||||
ptrace_report_syscall_entry(regs)) {
|
||||
regs->regs[0] = -ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
@ -484,5 +483,5 @@ asmlinkage void do_syscall_trace_leave(struct pt_regs *regs)
|
||||
|
||||
step = test_thread_flag(TIF_SINGLESTEP);
|
||||
if (step || test_thread_flag(TIF_SYSCALL_TRACE))
|
||||
tracehook_report_syscall_exit(regs, step);
|
||||
ptrace_report_syscall_exit(regs, step);
|
||||
}
|
||||
|
@ -25,7 +25,7 @@
|
||||
#include <linux/personality.h>
|
||||
#include <linux/binfmts.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/resume_user_mode.h>
|
||||
#include <asm/ucontext.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/cacheflush.h>
|
||||
@ -503,5 +503,5 @@ asmlinkage void do_notify_resume(struct pt_regs *regs, unsigned int save_r0,
|
||||
do_signal(regs, save_r0);
|
||||
|
||||
if (thread_info_flags & _TIF_NOTIFY_RESUME)
|
||||
tracehook_notify_resume(regs);
|
||||
resume_user_mode_work(regs);
|
||||
}
|
||||
|
@ -21,7 +21,6 @@
|
||||
#include <linux/signal.h>
|
||||
#include <linux/regset.h>
|
||||
#include <linux/elf.h>
|
||||
#include <linux/tracehook.h>
|
||||
|
||||
#include <linux/uaccess.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 (syscall_exit_p)
|
||||
tracehook_report_syscall_exit(regs, 0);
|
||||
ptrace_report_syscall_exit(regs, 0);
|
||||
else
|
||||
ret = tracehook_report_syscall_entry(regs);
|
||||
ret = ptrace_report_syscall_entry(regs);
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include <linux/audit.h>
|
||||
#include <linux/signal.h>
|
||||
#include <linux/regset.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <trace/syscall.h>
|
||||
#include <linux/compat.h>
|
||||
#include <linux/elf.h>
|
||||
@ -1095,7 +1094,7 @@ asmlinkage int syscall_trace_enter(struct pt_regs *regs)
|
||||
user_exit();
|
||||
|
||||
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)))
|
||||
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]);
|
||||
|
||||
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))
|
||||
user_enter();
|
||||
|
@ -20,7 +20,6 @@
|
||||
#include <linux/binfmts.h>
|
||||
#include <linux/compat.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/tracehook.h>
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/ptrace.h>
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include <linux/smp.h>
|
||||
#include <linux/binfmts.h> /* do_coredum */
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/resume_user_mode.h>
|
||||
|
||||
#include <linux/uaccess.h>
|
||||
#include <asm/ptrace.h>
|
||||
@ -524,7 +524,7 @@ void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0,
|
||||
if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
|
||||
do_signal(regs, orig_i0);
|
||||
if (thread_info_flags & _TIF_NOTIFY_RESUME)
|
||||
tracehook_notify_resume(regs);
|
||||
resume_user_mode_work(regs);
|
||||
}
|
||||
|
||||
asmlinkage int do_sys_sigstack(struct sigstack __user *ssptr,
|
||||
|
@ -15,7 +15,7 @@
|
||||
#include <linux/errno.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/resume_user_mode.h>
|
||||
#include <linux/unistd.h>
|
||||
#include <linux/mm.h>
|
||||
#include <linux/tty.h>
|
||||
@ -552,7 +552,7 @@ void do_notify_resume(struct pt_regs *regs, unsigned long orig_i0, unsigned long
|
||||
if (thread_info_flags & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
|
||||
do_signal(regs, orig_i0);
|
||||
if (thread_info_flags & _TIF_NOTIFY_RESUME)
|
||||
tracehook_notify_resume(regs);
|
||||
resume_user_mode_work(regs);
|
||||
user_enter();
|
||||
}
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
#include <linux/seq_file.h>
|
||||
#include <linux/tick.h>
|
||||
#include <linux/threads.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/resume_user_mode.h>
|
||||
#include <asm/current.h>
|
||||
#include <asm/mmu_context.h>
|
||||
#include <linux/uaccess.h>
|
||||
@ -104,7 +104,7 @@ void interrupt_end(void)
|
||||
test_thread_flag(TIF_NOTIFY_SIGNAL))
|
||||
do_signal(regs);
|
||||
if (test_thread_flag(TIF_NOTIFY_RESUME))
|
||||
tracehook_notify_resume(regs);
|
||||
resume_user_mode_work(regs);
|
||||
}
|
||||
|
||||
int get_current_pid(void)
|
||||
|
@ -6,7 +6,6 @@
|
||||
#include <linux/audit.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/sched.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/uaccess.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))
|
||||
return 0;
|
||||
|
||||
return tracehook_report_syscall_entry(regs);
|
||||
return ptrace_report_syscall_entry(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))
|
||||
return;
|
||||
|
||||
tracehook_report_syscall_exit(regs, 0);
|
||||
ptrace_report_syscall_exit(regs, 0);
|
||||
/* force do_signal() --> is_syscall() */
|
||||
if (ptraced & PT_PTRACED)
|
||||
set_thread_flag(TIF_SIGPENDING);
|
||||
|
@ -13,7 +13,6 @@
|
||||
#include <linux/errno.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/user.h>
|
||||
#include <linux/elf.h>
|
||||
#include <linux/security.h>
|
||||
|
@ -18,7 +18,6 @@
|
||||
#include <linux/kstrtox.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/wait.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/unistd.h>
|
||||
#include <linux/stddef.h>
|
||||
#include <linux/personality.h>
|
||||
@ -861,11 +860,11 @@ static inline unsigned long get_nr_restart_syscall(const struct pt_regs *regs)
|
||||
* want to handle. Thus you cannot kill init even with a SIGKILL even by
|
||||
* mistake.
|
||||
*/
|
||||
void arch_do_signal_or_restart(struct pt_regs *regs, bool has_signal)
|
||||
void arch_do_signal_or_restart(struct pt_regs *regs)
|
||||
{
|
||||
struct ksignal ksig;
|
||||
|
||||
if (has_signal && get_signal(&ksig)) {
|
||||
if (get_signal(&ksig)) {
|
||||
/* Whee! Actually deliver the signal. */
|
||||
handle_signal(&ksig, regs);
|
||||
return;
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/debugfs.h>
|
||||
#include <linux/sched/smt.h>
|
||||
#include <linux/task_work.h>
|
||||
|
||||
#include <asm/tlbflush.h>
|
||||
#include <asm/mmu_context.h>
|
||||
|
@ -26,7 +26,6 @@
|
||||
#include <linux/security.h>
|
||||
#include <linux/signal.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/uaccess.h>
|
||||
|
||||
#define CREATE_TRACE_POINTS
|
||||
@ -550,7 +549,7 @@ int do_syscall_trace_enter(struct pt_regs *regs)
|
||||
regs->areg[2] = -ENOSYS;
|
||||
|
||||
if (test_thread_flag(TIF_SYSCALL_TRACE) &&
|
||||
tracehook_report_syscall_entry(regs)) {
|
||||
ptrace_report_syscall_entry(regs)) {
|
||||
regs->areg[2] = -ENOSYS;
|
||||
regs->syscall = NO_SYSCALL;
|
||||
return 0;
|
||||
@ -583,5 +582,5 @@ void do_syscall_trace_leave(struct pt_regs *regs)
|
||||
step = test_thread_flag(TIF_SINGLESTEP);
|
||||
|
||||
if (step || test_thread_flag(TIF_SYSCALL_TRACE))
|
||||
tracehook_report_syscall_exit(regs, step);
|
||||
ptrace_report_syscall_exit(regs, step);
|
||||
}
|
||||
|
@ -19,7 +19,7 @@
|
||||
#include <linux/errno.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/personality.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/resume_user_mode.h>
|
||||
#include <linux/sched/task_stack.h>
|
||||
|
||||
#include <asm/ucontext.h>
|
||||
@ -511,5 +511,5 @@ void do_notify_resume(struct pt_regs *regs)
|
||||
do_signal(regs);
|
||||
|
||||
if (test_thread_flag(TIF_NOTIFY_RESUME))
|
||||
tracehook_notify_resume(regs);
|
||||
resume_user_mode_work(regs);
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
#include <linux/delay.h>
|
||||
#include <linux/atomic.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/resume_user_mode.h>
|
||||
#include <linux/psi.h>
|
||||
#include <linux/part_stat.h>
|
||||
#include "blk.h"
|
||||
|
@ -31,7 +31,6 @@
|
||||
#include <linux/tsacct_kern.h>
|
||||
#include <linux/cn_proc.h>
|
||||
#include <linux/audit.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/kmod.h>
|
||||
#include <linux/fsnotify.h>
|
||||
#include <linux/fs_struct.h>
|
||||
|
@ -56,7 +56,6 @@
|
||||
#include <linux/tsacct_kern.h>
|
||||
#include <linux/cn_proc.h>
|
||||
#include <linux/audit.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/kmod.h>
|
||||
#include <linux/fsnotify.h>
|
||||
#include <linux/fs_struct.h>
|
||||
|
@ -13,7 +13,7 @@
|
||||
#include <linux/slab.h>
|
||||
#include <linux/rculist_nulls.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/task_work.h>
|
||||
#include <linux/audit.h>
|
||||
#include <uapi/linux/io_uring.h>
|
||||
|
||||
@ -522,7 +522,9 @@ static bool io_flush_signals(void)
|
||||
{
|
||||
if (unlikely(test_thread_flag(TIF_NOTIFY_SIGNAL))) {
|
||||
__set_current_state(TASK_RUNNING);
|
||||
tracehook_notify_signal();
|
||||
clear_notify_signal();
|
||||
if (task_work_pending(current))
|
||||
task_work_run();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -79,7 +79,6 @@
|
||||
#include <linux/task_work.h>
|
||||
#include <linux/pagemap.h>
|
||||
#include <linux/io_uring.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/audit.h>
|
||||
#include <linux/security.h>
|
||||
|
||||
@ -2750,9 +2749,11 @@ static inline unsigned int io_sqring_entries(struct io_ring_ctx *ctx)
|
||||
|
||||
static inline bool io_run_task_work(void)
|
||||
{
|
||||
if (test_thread_flag(TIF_NOTIFY_SIGNAL) || current->task_works) {
|
||||
if (test_thread_flag(TIF_NOTIFY_SIGNAL) || task_work_pending(current)) {
|
||||
__set_current_state(TASK_RUNNING);
|
||||
tracehook_notify_signal();
|
||||
clear_notify_signal();
|
||||
if (task_work_pending(current))
|
||||
task_work_run();
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -8041,7 +8042,7 @@ static int io_sq_thread(void *data)
|
||||
}
|
||||
|
||||
prepare_to_wait(&sqd->wait, &wait, TASK_INTERRUPTIBLE);
|
||||
if (!io_sqd_events_pending(sqd) && !current->task_works) {
|
||||
if (!io_sqd_events_pending(sqd) && !task_work_pending(current)) {
|
||||
bool needs_sched = true;
|
||||
|
||||
list_for_each_entry(ctx, &sqd->ctx_list, sqd_list) {
|
||||
@ -11096,7 +11097,7 @@ static __cold void __io_uring_show_fdinfo(struct io_ring_ctx *ctx,
|
||||
|
||||
hlist_for_each_entry(req, list, hash_node)
|
||||
seq_printf(m, " op=%d, task_works=%d\n", req->opcode,
|
||||
req->task->task_works != NULL);
|
||||
task_work_pending(req->task));
|
||||
}
|
||||
|
||||
seq_puts(m, "CqOverflowList:\n");
|
||||
|
@ -88,7 +88,6 @@
|
||||
#include <linux/pid_namespace.h>
|
||||
#include <linux/prctl.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/string_helpers.h>
|
||||
#include <linux/user_namespace.h>
|
||||
#include <linux/fs_struct.h>
|
||||
|
@ -74,7 +74,6 @@
|
||||
#include <linux/mount.h>
|
||||
#include <linux/security.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/printk.h>
|
||||
#include <linux/cache.h>
|
||||
#include <linux/cgroup.h>
|
||||
|
@ -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
|
||||
* 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.
|
||||
*
|
||||
* This rolls back the register state in @regs so it's as if the
|
||||
|
@ -3,7 +3,7 @@
|
||||
#define __LINUX_ENTRYCOMMON_H
|
||||
|
||||
#include <linux/static_call_types.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/seccomp.h>
|
||||
#include <linux/sched.h>
|
||||
@ -79,26 +79,6 @@ static __always_inline void arch_check_user_regs(struct pt_regs *regs);
|
||||
static __always_inline void arch_check_user_regs(struct pt_regs *regs) {}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* arch_syscall_enter_tracehook - Wrapper around tracehook_report_syscall_entry()
|
||||
* @regs: Pointer to currents pt_regs
|
||||
*
|
||||
* Returns: 0 on success or an error code to skip the syscall.
|
||||
*
|
||||
* Defaults to tracehook_report_syscall_entry(). Can be replaced by
|
||||
* architecture specific code.
|
||||
*
|
||||
* Invoked from syscall_enter_from_user_mode()
|
||||
*/
|
||||
static inline __must_check int arch_syscall_enter_tracehook(struct pt_regs *regs);
|
||||
|
||||
#ifndef arch_syscall_enter_tracehook
|
||||
static inline __must_check int arch_syscall_enter_tracehook(struct pt_regs *regs)
|
||||
{
|
||||
return tracehook_report_syscall_entry(regs);
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* enter_from_user_mode - Establish state when coming from user mode
|
||||
*
|
||||
@ -157,7 +137,7 @@ void syscall_enter_from_user_mode_prepare(struct pt_regs *regs);
|
||||
* It handles the following work items:
|
||||
*
|
||||
* 1) syscall_work flag dependent invocations of
|
||||
* arch_syscall_enter_tracehook(), __secure_computing(), trace_sys_enter()
|
||||
* ptrace_report_syscall_entry(), __secure_computing(), trace_sys_enter()
|
||||
* 2) Invocation of audit_syscall_entry()
|
||||
*/
|
||||
long syscall_enter_from_user_mode_work(struct pt_regs *regs, long syscall);
|
||||
@ -277,26 +257,7 @@ static __always_inline void arch_exit_to_user_mode(void) { }
|
||||
*
|
||||
* Invoked from exit_to_user_mode_loop().
|
||||
*/
|
||||
void arch_do_signal_or_restart(struct pt_regs *regs, bool has_signal);
|
||||
|
||||
/**
|
||||
* arch_syscall_exit_tracehook - Wrapper around tracehook_report_syscall_exit()
|
||||
* @regs: Pointer to currents pt_regs
|
||||
* @step: Indicator for single step
|
||||
*
|
||||
* Defaults to tracehook_report_syscall_exit(). Can be replaced by
|
||||
* architecture specific code.
|
||||
*
|
||||
* Invoked from syscall_exit_to_user_mode()
|
||||
*/
|
||||
static inline void arch_syscall_exit_tracehook(struct pt_regs *regs, bool step);
|
||||
|
||||
#ifndef arch_syscall_exit_tracehook
|
||||
static inline void arch_syscall_exit_tracehook(struct pt_regs *regs, bool step)
|
||||
{
|
||||
tracehook_report_syscall_exit(regs, step);
|
||||
}
|
||||
#endif
|
||||
void arch_do_signal_or_restart(struct pt_regs *regs);
|
||||
|
||||
/**
|
||||
* exit_to_user_mode - Fixup state when exiting to user mode
|
||||
@ -347,7 +308,7 @@ void syscall_exit_to_user_mode_work(struct pt_regs *regs);
|
||||
* - rseq syscall exit
|
||||
* - audit
|
||||
* - syscall tracing
|
||||
* - tracehook (single stepping)
|
||||
* - ptrace (single stepping)
|
||||
*
|
||||
* 2) Preparatory work
|
||||
* - Exit to user mode loop (common TIF handling). Invokes
|
||||
|
@ -3,7 +3,7 @@
|
||||
#define __LINUX_ENTRYKVM_H
|
||||
|
||||
#include <linux/static_call_types.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/resume_user_mode.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/seccomp.h>
|
||||
#include <linux/sched.h>
|
||||
|
@ -6,7 +6,6 @@
|
||||
#include <linux/list.h>
|
||||
#include <linux/alarmtimer.h>
|
||||
#include <linux/timerqueue.h>
|
||||
#include <linux/task_work.h>
|
||||
|
||||
struct kernel_siginfo;
|
||||
struct task_struct;
|
||||
|
@ -60,7 +60,7 @@ extern int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned
|
||||
extern void ptrace_disable(struct task_struct *);
|
||||
extern int ptrace_request(struct task_struct *child, long request,
|
||||
unsigned long addr, unsigned long data);
|
||||
extern void ptrace_notify(int exit_code);
|
||||
extern int ptrace_notify(int exit_code, unsigned long message);
|
||||
extern void __ptrace_link(struct task_struct *child,
|
||||
struct task_struct *new_parent,
|
||||
const struct cred *ptracer_cred);
|
||||
@ -155,8 +155,7 @@ static inline bool ptrace_event_enabled(struct task_struct *task, int event)
|
||||
static inline void ptrace_event(int event, unsigned long message)
|
||||
{
|
||||
if (unlikely(ptrace_event_enabled(current, event))) {
|
||||
current->ptrace_message = message;
|
||||
ptrace_notify((event << 8) | SIGTRAP);
|
||||
ptrace_notify((event << 8) | SIGTRAP, message);
|
||||
} else if (event == PTRACE_EVENT_EXEC) {
|
||||
/* legacy EXEC report via SIGTRAP */
|
||||
if ((current->ptrace & (PT_PTRACED|PT_SEIZED)) == PT_PTRACED)
|
||||
@ -413,4 +412,80 @@ static inline void user_single_step_report(struct pt_regs *regs)
|
||||
extern int task_current_syscall(struct task_struct *target, struct syscall_info *info);
|
||||
|
||||
extern void sigaction_compat_abi(struct k_sigaction *act, struct k_sigaction *oact);
|
||||
|
||||
/*
|
||||
* ptrace report for syscall entry and exit looks identical.
|
||||
*/
|
||||
static inline int ptrace_report_syscall(unsigned long message)
|
||||
{
|
||||
int ptrace = current->ptrace;
|
||||
int signr;
|
||||
|
||||
if (!(ptrace & PT_PTRACED))
|
||||
return 0;
|
||||
|
||||
signr = ptrace_notify(SIGTRAP | ((ptrace & PT_TRACESYSGOOD) ? 0x80 : 0),
|
||||
message);
|
||||
|
||||
/*
|
||||
* 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
|
||||
* stopping signal is not SIGTRAP. -brl
|
||||
*/
|
||||
if (signr)
|
||||
send_sig(signr, current, 1);
|
||||
|
||||
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
|
||||
|
64
include/linux/resume_user_mode.h
Normal file
64
include/linux/resume_user_mode.h
Normal file
@ -0,0 +1,64 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
|
||||
#ifndef LINUX_RESUME_USER_MODE_H
|
||||
#define LINUX_RESUME_USER_MODE_H
|
||||
|
||||
#include <linux/sched.h>
|
||||
#include <linux/task_work.h>
|
||||
#include <linux/memcontrol.h>
|
||||
#include <linux/blk-cgroup.h>
|
||||
|
||||
/**
|
||||
* set_notify_resume - cause resume_user_mode_work() to be called
|
||||
* @task: task that will call resume_user_mode_work()
|
||||
*
|
||||
* Calling this arranges that @task will call resume_user_mode_work()
|
||||
* before returning to user mode. If it's already running in user mode,
|
||||
* it will enter the kernel and call resume_user_mode_work() soon.
|
||||
* If it's blocked, it will not be woken.
|
||||
*/
|
||||
static inline void set_notify_resume(struct task_struct *task)
|
||||
{
|
||||
if (!test_and_set_tsk_thread_flag(task, TIF_NOTIFY_RESUME))
|
||||
kick_process(task);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* resume_user_mode_work - Perform work before returning to user mode
|
||||
* @regs: user-mode registers of @current task
|
||||
*
|
||||
* This is called when %TIF_NOTIFY_RESUME has been set. Now we are
|
||||
* about to return to user mode, and the user state in @regs can be
|
||||
* inspected or adjusted. The caller in arch code has cleared
|
||||
* %TIF_NOTIFY_RESUME before the call. If the flag gets set again
|
||||
* asynchronously, this will be called again before we return to
|
||||
* user mode.
|
||||
*
|
||||
* Called without locks.
|
||||
*/
|
||||
static inline void resume_user_mode_work(struct pt_regs *regs)
|
||||
{
|
||||
clear_thread_flag(TIF_NOTIFY_RESUME);
|
||||
/*
|
||||
* This barrier pairs with task_work_add()->set_notify_resume() after
|
||||
* hlist_add_head(task->task_works);
|
||||
*/
|
||||
smp_mb__after_atomic();
|
||||
if (unlikely(task_work_pending(current)))
|
||||
task_work_run();
|
||||
|
||||
#ifdef CONFIG_KEYS_REQUEST_CACHE
|
||||
if (unlikely(current->cached_requested_key)) {
|
||||
key_put(current->cached_requested_key);
|
||||
current->cached_requested_key = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
mem_cgroup_handle_over_high();
|
||||
blkcg_maybe_throttle_current();
|
||||
|
||||
rseq_handle_notify_resume(NULL, regs);
|
||||
}
|
||||
|
||||
#endif /* LINUX_RESUME_USER_MODE_H */
|
@ -349,6 +349,23 @@ extern void sigqueue_free(struct sigqueue *);
|
||||
extern int send_sigqueue(struct sigqueue *, struct pid *, enum pid_type);
|
||||
extern int do_sigaction(int, struct k_sigaction *, struct k_sigaction *);
|
||||
|
||||
static inline void clear_notify_signal(void)
|
||||
{
|
||||
clear_thread_flag(TIF_NOTIFY_SIGNAL);
|
||||
smp_mb__after_atomic();
|
||||
}
|
||||
|
||||
/*
|
||||
* Called to break out of interruptible wait loops, and enter the
|
||||
* exit_to_user_mode_loop().
|
||||
*/
|
||||
static inline void set_notify_signal(struct task_struct *task)
|
||||
{
|
||||
if (!test_and_set_tsk_thread_flag(task, TIF_NOTIFY_SIGNAL) &&
|
||||
!wake_up_state(task, TASK_INTERRUPTIBLE))
|
||||
kick_process(task);
|
||||
}
|
||||
|
||||
static inline int restart_syscall(void)
|
||||
{
|
||||
set_tsk_thread_flag(current, TIF_SIGPENDING);
|
||||
|
@ -19,6 +19,11 @@ enum task_work_notify_mode {
|
||||
TWA_SIGNAL,
|
||||
};
|
||||
|
||||
static inline bool task_work_pending(struct task_struct *task)
|
||||
{
|
||||
return READ_ONCE(task->task_works);
|
||||
}
|
||||
|
||||
int task_work_add(struct task_struct *task, struct callback_head *twork,
|
||||
enum task_work_notify_mode mode);
|
||||
|
||||
|
@ -1,226 +0,0 @@
|
||||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* Tracing hooks
|
||||
*
|
||||
* Copyright (C) 2008-2009 Red Hat, Inc. All rights reserved.
|
||||
*
|
||||
* This file defines hook entry points called by core code where
|
||||
* user tracing/debugging support might need to do something. These
|
||||
* entry points are called tracehook_*(). Each hook declared below
|
||||
* has a detailed kerneldoc comment giving the context (locking et
|
||||
* al) from which it is called, and the meaning of its return value.
|
||||
*
|
||||
* Each function here typically has only one call site, so it is ok
|
||||
* to have some nontrivial tracehook_*() inlines. In all cases, the
|
||||
* fast path when no tracing is enabled should be very short.
|
||||
*
|
||||
* The purpose of this file and the tracehook_* layer is to consolidate
|
||||
* the interface that the kernel core and arch code uses to enable any
|
||||
* user debugging or tracing facility (such as ptrace). The interfaces
|
||||
* here are carefully documented so that maintainers of core and arch
|
||||
* code do not need to think about the implementation details of the
|
||||
* tracing facilities. Likewise, maintainers of the tracing code do not
|
||||
* need to understand all the calling core or arch code in detail, just
|
||||
* documented circumstances of each call, such as locking conditions.
|
||||
*
|
||||
* If the calling core code changes so that locking is different, then
|
||||
* it is ok to change the interface documented here. The maintainer of
|
||||
* core code changing should notify the maintainers of the tracing code
|
||||
* that they need to work out the change.
|
||||
*
|
||||
* Some tracehook_*() inlines take arguments that the current tracing
|
||||
* implementations might not necessarily use. These function signatures
|
||||
* are chosen to pass in all the information that is on hand in the
|
||||
* caller and might conceivably be relevant to a tracer, so that the
|
||||
* core code won't have to be updated when tracing adds more features.
|
||||
* If a call site changes so that some of those parameters are no longer
|
||||
* already on hand without extra work, then the tracehook_* interface
|
||||
* can change so there is no make-work burden on the core code. The
|
||||
* maintainer of core code changing should notify the maintainers of the
|
||||
* tracing code that they need to work out the change.
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_TRACEHOOK_H
|
||||
#define _LINUX_TRACEHOOK_H 1
|
||||
|
||||
#include <linux/sched.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/security.h>
|
||||
#include <linux/task_work.h>
|
||||
#include <linux/memcontrol.h>
|
||||
#include <linux/blk-cgroup.h>
|
||||
struct linux_binprm;
|
||||
|
||||
/*
|
||||
* ptrace report for syscall entry and exit looks identical.
|
||||
*/
|
||||
static inline int ptrace_report_syscall(unsigned long message)
|
||||
{
|
||||
int ptrace = current->ptrace;
|
||||
|
||||
if (!(ptrace & PT_PTRACED))
|
||||
return 0;
|
||||
|
||||
current->ptrace_message = message;
|
||||
ptrace_notify(SIGTRAP | ((ptrace & PT_TRACESYSGOOD) ? 0x80 : 0));
|
||||
|
||||
/*
|
||||
* 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
|
||||
* stopping signal is not SIGTRAP. -brl
|
||||
*/
|
||||
if (current->exit_code) {
|
||||
send_sig(current->exit_code, current, 1);
|
||||
current->exit_code = 0;
|
||||
}
|
||||
|
||||
current->ptrace_message = 0;
|
||||
return fatal_signal_pending(current);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
* @stepping: nonzero if debugger single-step or block-step in use
|
||||
*
|
||||
* Called by the arch code after a signal handler has been set up.
|
||||
* Register and stack state reflects the user handler about to run.
|
||||
* Signal mask changes have already been made.
|
||||
*
|
||||
* Called without locks, shortly before returning to user mode
|
||||
* (or handling more signals).
|
||||
*/
|
||||
static inline void tracehook_signal_handler(int stepping)
|
||||
{
|
||||
if (stepping)
|
||||
ptrace_notify(SIGTRAP);
|
||||
}
|
||||
|
||||
/**
|
||||
* set_notify_resume - cause tracehook_notify_resume() to be called
|
||||
* @task: task that will call tracehook_notify_resume()
|
||||
*
|
||||
* Calling this arranges that @task will call tracehook_notify_resume()
|
||||
* before returning to user mode. If it's already running in user mode,
|
||||
* it will enter the kernel and call tracehook_notify_resume() soon.
|
||||
* If it's blocked, it will not be woken.
|
||||
*/
|
||||
static inline void set_notify_resume(struct task_struct *task)
|
||||
{
|
||||
#ifdef TIF_NOTIFY_RESUME
|
||||
if (!test_and_set_tsk_thread_flag(task, TIF_NOTIFY_RESUME))
|
||||
kick_process(task);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* tracehook_notify_resume - report when about to return to user mode
|
||||
* @regs: user-mode registers of @current task
|
||||
*
|
||||
* This is called when %TIF_NOTIFY_RESUME has been set. Now we are
|
||||
* about to return to user mode, and the user state in @regs can be
|
||||
* inspected or adjusted. The caller in arch code has cleared
|
||||
* %TIF_NOTIFY_RESUME before the call. If the flag gets set again
|
||||
* asynchronously, this will be called again before we return to
|
||||
* user mode.
|
||||
*
|
||||
* Called without locks.
|
||||
*/
|
||||
static inline void tracehook_notify_resume(struct pt_regs *regs)
|
||||
{
|
||||
clear_thread_flag(TIF_NOTIFY_RESUME);
|
||||
/*
|
||||
* This barrier pairs with task_work_add()->set_notify_resume() after
|
||||
* hlist_add_head(task->task_works);
|
||||
*/
|
||||
smp_mb__after_atomic();
|
||||
if (unlikely(current->task_works))
|
||||
task_work_run();
|
||||
|
||||
#ifdef CONFIG_KEYS_REQUEST_CACHE
|
||||
if (unlikely(current->cached_requested_key)) {
|
||||
key_put(current->cached_requested_key);
|
||||
current->cached_requested_key = NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
mem_cgroup_handle_over_high();
|
||||
blkcg_maybe_throttle_current();
|
||||
|
||||
rseq_handle_notify_resume(NULL, regs);
|
||||
}
|
||||
|
||||
/*
|
||||
* called by exit_to_user_mode_loop() if ti_work & _TIF_NOTIFY_SIGNAL. This
|
||||
* is currently used by TWA_SIGNAL based task_work, which requires breaking
|
||||
* wait loops to ensure that task_work is noticed and run.
|
||||
*/
|
||||
static inline void tracehook_notify_signal(void)
|
||||
{
|
||||
clear_thread_flag(TIF_NOTIFY_SIGNAL);
|
||||
smp_mb__after_atomic();
|
||||
if (current->task_works)
|
||||
task_work_run();
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when we have work to process from exit_to_user_mode_loop()
|
||||
*/
|
||||
static inline void set_notify_signal(struct task_struct *task)
|
||||
{
|
||||
if (!test_and_set_tsk_thread_flag(task, TIF_NOTIFY_SIGNAL) &&
|
||||
!wake_up_state(task, TASK_INTERRUPTIBLE))
|
||||
kick_process(task);
|
||||
}
|
||||
|
||||
#endif /* <linux/tracehook.h> */
|
@ -114,7 +114,7 @@ struct ptrace_rseq_configuration {
|
||||
|
||||
/*
|
||||
* These values are stored in task->ptrace_message
|
||||
* by tracehook_report_syscall_* to describe the current syscall-stop.
|
||||
* by ptrace_stop to describe the current syscall-stop.
|
||||
*/
|
||||
#define PTRACE_EVENTMSG_SYSCALL_ENTRY 1
|
||||
#define PTRACE_EVENTMSG_SYSCALL_EXIT 2
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
#include <linux/context_tracking.h>
|
||||
#include <linux/entry-common.h>
|
||||
#include <linux/resume_user_mode.h>
|
||||
#include <linux/highmem.h>
|
||||
#include <linux/jump_label.h>
|
||||
#include <linux/livepatch.h>
|
||||
@ -59,7 +60,7 @@ static long syscall_trace_enter(struct pt_regs *regs, long syscall,
|
||||
|
||||
/* Handle ptrace */
|
||||
if (work & (SYSCALL_WORK_SYSCALL_TRACE | SYSCALL_WORK_SYSCALL_EMU)) {
|
||||
ret = arch_syscall_enter_tracehook(regs);
|
||||
ret = ptrace_report_syscall_entry(regs);
|
||||
if (ret || (work & SYSCALL_WORK_SYSCALL_EMU))
|
||||
return -1L;
|
||||
}
|
||||
@ -139,15 +140,7 @@ void noinstr exit_to_user_mode(void)
|
||||
}
|
||||
|
||||
/* Workaround to allow gradual conversion of architecture code */
|
||||
void __weak arch_do_signal_or_restart(struct pt_regs *regs, bool has_signal) { }
|
||||
|
||||
static void handle_signal_work(struct pt_regs *regs, unsigned long ti_work)
|
||||
{
|
||||
if (ti_work & _TIF_NOTIFY_SIGNAL)
|
||||
tracehook_notify_signal();
|
||||
|
||||
arch_do_signal_or_restart(regs, ti_work & _TIF_SIGPENDING);
|
||||
}
|
||||
void __weak arch_do_signal_or_restart(struct pt_regs *regs) { }
|
||||
|
||||
#ifdef CONFIG_RT_DELAYED_SIGNALS
|
||||
static inline void raise_delayed_signal(void)
|
||||
@ -184,10 +177,10 @@ static unsigned long exit_to_user_mode_loop(struct pt_regs *regs,
|
||||
klp_update_patch_state(current);
|
||||
|
||||
if (ti_work & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL))
|
||||
handle_signal_work(regs, ti_work);
|
||||
arch_do_signal_or_restart(regs);
|
||||
|
||||
if (ti_work & _TIF_NOTIFY_RESUME)
|
||||
tracehook_notify_resume(regs);
|
||||
resume_user_mode_work(regs);
|
||||
|
||||
/* Architecture specific TIF work */
|
||||
arch_exit_to_user_mode_work(regs, ti_work);
|
||||
@ -267,7 +260,7 @@ static void syscall_exit_work(struct pt_regs *regs, unsigned long work)
|
||||
|
||||
step = report_single_step(work);
|
||||
if (step || work & SYSCALL_WORK_SYSCALL_TRACE)
|
||||
arch_syscall_exit_tracehook(regs, step);
|
||||
ptrace_report_syscall_exit(regs, step);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -8,8 +8,11 @@ static int xfer_to_guest_mode_work(struct kvm_vcpu *vcpu, unsigned long ti_work)
|
||||
do {
|
||||
int ret;
|
||||
|
||||
if (ti_work & _TIF_NOTIFY_SIGNAL)
|
||||
tracehook_notify_signal();
|
||||
if (ti_work & (_TIF_SIGPENDING | _TIF_NOTIFY_SIGNAL)) {
|
||||
clear_notify_signal();
|
||||
if (task_work_pending(current))
|
||||
task_work_run();
|
||||
}
|
||||
|
||||
if (ti_work & _TIF_SIGPENDING) {
|
||||
kvm_handle_signal_exit(vcpu);
|
||||
@ -20,7 +23,7 @@ static int xfer_to_guest_mode_work(struct kvm_vcpu *vcpu, unsigned long ti_work)
|
||||
schedule();
|
||||
|
||||
if (ti_work & _TIF_NOTIFY_RESUME)
|
||||
tracehook_notify_resume(NULL);
|
||||
resume_user_mode_work(NULL);
|
||||
|
||||
ret = arch_xfer_to_guest_mode_handle_work(vcpu, ti_work);
|
||||
if (ret)
|
||||
|
@ -49,7 +49,8 @@
|
||||
#include <linux/audit.h> /* for audit_free() */
|
||||
#include <linux/resource.h>
|
||||
#include <linux/task_io_accounting_ops.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/blkdev.h>
|
||||
#include <linux/task_work.h>
|
||||
#include <linux/fs_struct.h>
|
||||
#include <linux/init_task.h>
|
||||
#include <linux/perf_event.h>
|
||||
|
@ -9,7 +9,6 @@
|
||||
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/stacktrace.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include "core.h"
|
||||
#include "patch.h"
|
||||
#include "transition.h"
|
||||
|
@ -371,6 +371,26 @@ bool ptrace_may_access(struct task_struct *task, unsigned int mode)
|
||||
return !err;
|
||||
}
|
||||
|
||||
static int check_ptrace_options(unsigned long data)
|
||||
{
|
||||
if (data & ~(unsigned long)PTRACE_O_MASK)
|
||||
return -EINVAL;
|
||||
|
||||
if (unlikely(data & PTRACE_O_SUSPEND_SECCOMP)) {
|
||||
if (!IS_ENABLED(CONFIG_CHECKPOINT_RESTORE) ||
|
||||
!IS_ENABLED(CONFIG_SECCOMP))
|
||||
return -EINVAL;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
if (seccomp_mode(¤t->seccomp) != SECCOMP_MODE_DISABLED ||
|
||||
current->ptrace & PT_SUSPEND_SECCOMP)
|
||||
return -EPERM;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ptrace_attach(struct task_struct *task, long request,
|
||||
unsigned long addr,
|
||||
unsigned long flags)
|
||||
@ -382,8 +402,16 @@ static int ptrace_attach(struct task_struct *task, long request,
|
||||
if (seize) {
|
||||
if (addr != 0)
|
||||
goto out;
|
||||
/*
|
||||
* This duplicates the check in check_ptrace_options() because
|
||||
* ptrace_attach() and ptrace_setoptions() have historically
|
||||
* used different error codes for unknown ptrace options.
|
||||
*/
|
||||
if (flags & ~(unsigned long)PTRACE_O_MASK)
|
||||
goto out;
|
||||
retval = check_ptrace_options(flags);
|
||||
if (retval)
|
||||
return retval;
|
||||
flags = PT_PTRACED | PT_SEIZED | (flags << PT_OPT_FLAG_SHIFT);
|
||||
} else {
|
||||
flags = PT_PTRACED;
|
||||
@ -654,22 +682,11 @@ int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long ds
|
||||
static int ptrace_setoptions(struct task_struct *child, unsigned long data)
|
||||
{
|
||||
unsigned flags;
|
||||
int ret;
|
||||
|
||||
if (data & ~(unsigned long)PTRACE_O_MASK)
|
||||
return -EINVAL;
|
||||
|
||||
if (unlikely(data & PTRACE_O_SUSPEND_SECCOMP)) {
|
||||
if (!IS_ENABLED(CONFIG_CHECKPOINT_RESTORE) ||
|
||||
!IS_ENABLED(CONFIG_SECCOMP))
|
||||
return -EINVAL;
|
||||
|
||||
if (!capable(CAP_SYS_ADMIN))
|
||||
return -EPERM;
|
||||
|
||||
if (seccomp_mode(¤t->seccomp) != SECCOMP_MODE_DISABLED ||
|
||||
current->ptrace & PT_SUSPEND_SECCOMP)
|
||||
return -EPERM;
|
||||
}
|
||||
ret = check_ptrace_options(data);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* Avoid intermediate state when all opts are cleared */
|
||||
flags = child->ptrace;
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include <linux/profile.h>
|
||||
#include <linux/psi.h>
|
||||
#include <linux/ratelimit.h>
|
||||
#include <linux/task_work.h>
|
||||
|
||||
#include <asm/switch_to.h>
|
||||
|
||||
|
@ -42,7 +42,6 @@
|
||||
#include <linux/pid.h>
|
||||
#include <linux/ptrace.h>
|
||||
#include <linux/capability.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/anon_inodes.h>
|
||||
#include <linux/lockdep.h>
|
||||
|
@ -32,7 +32,7 @@
|
||||
#include <linux/signal.h>
|
||||
#include <linux/signalfd.h>
|
||||
#include <linux/ratelimit.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/task_work.h>
|
||||
#include <linux/capability.h>
|
||||
#include <linux/freezer.h>
|
||||
#include <linux/pid_namespace.h>
|
||||
@ -2229,14 +2229,17 @@ static void do_notify_parent_cldstop(struct task_struct *tsk,
|
||||
* That makes it a way to test a stopped process for
|
||||
* being ptrace-stopped vs being job-control-stopped.
|
||||
*
|
||||
* If we actually decide not to stop at all because the tracer
|
||||
* is gone, we keep current->exit_code unless clear_code.
|
||||
* Returns the signal the ptracer requested the code resume
|
||||
* with. If the code did not stop because the tracer is gone,
|
||||
* the stop signal remains unchanged unless clear_code.
|
||||
*/
|
||||
static void ptrace_stop(int exit_code, int why, int clear_code, kernel_siginfo_t *info)
|
||||
static int ptrace_stop(int exit_code, int why, int clear_code,
|
||||
unsigned long message, kernel_siginfo_t *info)
|
||||
__releases(¤t->sighand->siglock)
|
||||
__acquires(¤t->sighand->siglock)
|
||||
{
|
||||
bool gstop_done = false;
|
||||
bool read_code = true;
|
||||
|
||||
if (arch_ptrace_stop_needed()) {
|
||||
/*
|
||||
@ -2278,6 +2281,7 @@ static void ptrace_stop(int exit_code, int why, int clear_code, kernel_siginfo_t
|
||||
*/
|
||||
smp_wmb();
|
||||
|
||||
current->ptrace_message = message;
|
||||
current->last_siginfo = info;
|
||||
current->exit_code = exit_code;
|
||||
|
||||
@ -2344,8 +2348,9 @@ static void ptrace_stop(int exit_code, int why, int clear_code, kernel_siginfo_t
|
||||
|
||||
/* tasklist protects us from ptrace_freeze_traced() */
|
||||
__set_current_state(TASK_RUNNING);
|
||||
read_code = false;
|
||||
if (clear_code)
|
||||
current->exit_code = 0;
|
||||
exit_code = 0;
|
||||
read_unlock(&tasklist_lock);
|
||||
}
|
||||
|
||||
@ -2355,7 +2360,11 @@ static void ptrace_stop(int exit_code, int why, int clear_code, kernel_siginfo_t
|
||||
* any signal-sending on another CPU that wants to examine it.
|
||||
*/
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
if (read_code)
|
||||
exit_code = current->exit_code;
|
||||
current->last_siginfo = NULL;
|
||||
current->ptrace_message = 0;
|
||||
current->exit_code = 0;
|
||||
|
||||
/* LISTENING can be set only during STOP traps, clear it */
|
||||
current->jobctl &= ~JOBCTL_LISTENING;
|
||||
@ -2366,9 +2375,10 @@ static void ptrace_stop(int exit_code, int why, int clear_code, kernel_siginfo_t
|
||||
* This sets TIF_SIGPENDING, but never clears it.
|
||||
*/
|
||||
recalc_sigpending_tsk(current);
|
||||
return exit_code;
|
||||
}
|
||||
|
||||
static void ptrace_do_notify(int signr, int exit_code, int why)
|
||||
static int ptrace_do_notify(int signr, int exit_code, int why, unsigned long message)
|
||||
{
|
||||
kernel_siginfo_t info;
|
||||
|
||||
@ -2379,18 +2389,21 @@ static void ptrace_do_notify(int signr, int exit_code, int why)
|
||||
info.si_uid = from_kuid_munged(current_user_ns(), current_uid());
|
||||
|
||||
/* Let the debugger run. */
|
||||
ptrace_stop(exit_code, why, 1, &info);
|
||||
return ptrace_stop(exit_code, why, 1, message, &info);
|
||||
}
|
||||
|
||||
void ptrace_notify(int exit_code)
|
||||
int ptrace_notify(int exit_code, unsigned long message)
|
||||
{
|
||||
int signr;
|
||||
|
||||
BUG_ON((exit_code & (0x7f | ~0xffff)) != SIGTRAP);
|
||||
if (unlikely(current->task_works))
|
||||
if (unlikely(task_work_pending(current)))
|
||||
task_work_run();
|
||||
|
||||
spin_lock_irq(¤t->sighand->siglock);
|
||||
ptrace_do_notify(SIGTRAP, exit_code, CLD_TRAPPED);
|
||||
signr = ptrace_do_notify(SIGTRAP, exit_code, CLD_TRAPPED, message);
|
||||
spin_unlock_irq(¤t->sighand->siglock);
|
||||
return signr;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -2545,11 +2558,10 @@ static void do_jobctl_trap(void)
|
||||
signr = SIGTRAP;
|
||||
WARN_ON_ONCE(!signr);
|
||||
ptrace_do_notify(signr, signr | (PTRACE_EVENT_STOP << 8),
|
||||
CLD_STOPPED);
|
||||
CLD_STOPPED, 0);
|
||||
} else {
|
||||
WARN_ON_ONCE(!signr);
|
||||
ptrace_stop(signr, CLD_STOPPED, 0, NULL);
|
||||
current->exit_code = 0;
|
||||
ptrace_stop(signr, CLD_STOPPED, 0, 0, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
@ -2602,15 +2614,12 @@ static int ptrace_signal(int signr, kernel_siginfo_t *info, enum pid_type type)
|
||||
* comment in dequeue_signal().
|
||||
*/
|
||||
current->jobctl |= JOBCTL_STOP_DEQUEUED;
|
||||
ptrace_stop(signr, CLD_TRAPPED, 0, info);
|
||||
signr = ptrace_stop(signr, CLD_TRAPPED, 0, 0, info);
|
||||
|
||||
/* We're back. Did the debugger cancel the sig? */
|
||||
signr = current->exit_code;
|
||||
if (signr == 0)
|
||||
return signr;
|
||||
|
||||
current->exit_code = 0;
|
||||
|
||||
/*
|
||||
* Update the siginfo structure if the signal has
|
||||
* changed. If the debugger wanted something
|
||||
@ -2667,20 +2676,12 @@ bool get_signal(struct ksignal *ksig)
|
||||
struct signal_struct *signal = current->signal;
|
||||
int signr;
|
||||
|
||||
if (unlikely(current->task_works))
|
||||
clear_notify_signal();
|
||||
if (unlikely(task_work_pending(current)))
|
||||
task_work_run();
|
||||
|
||||
/*
|
||||
* For non-generic architectures, check for TIF_NOTIFY_SIGNAL so
|
||||
* that the arch handlers don't all have to do it. If we get here
|
||||
* without TIF_SIGPENDING, just exit after running signal work.
|
||||
*/
|
||||
if (!IS_ENABLED(CONFIG_GENERIC_ENTRY)) {
|
||||
if (test_thread_flag(TIF_NOTIFY_SIGNAL))
|
||||
tracehook_notify_signal();
|
||||
if (!task_sigpending(current))
|
||||
return false;
|
||||
}
|
||||
if (!task_sigpending(current))
|
||||
return false;
|
||||
|
||||
if (unlikely(uprobe_deny_signal()))
|
||||
return false;
|
||||
@ -2939,7 +2940,8 @@ static void signal_delivered(struct ksignal *ksig, int stepping)
|
||||
set_current_blocked(&blocked);
|
||||
if (current->sas_ss_flags & SS_AUTODISARM)
|
||||
sas_ss_reset(current);
|
||||
tracehook_signal_handler(stepping);
|
||||
if (stepping)
|
||||
ptrace_notify(SIGTRAP, 0);
|
||||
}
|
||||
|
||||
void signal_setup_done(int failed, struct ksignal *ksig, int stepping)
|
||||
|
@ -1,7 +1,7 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/task_work.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/resume_user_mode.h>
|
||||
|
||||
static struct callback_head work_exited; /* all we need is ->next == NULL */
|
||||
|
||||
@ -78,7 +78,7 @@ task_work_cancel_match(struct task_struct *task,
|
||||
struct callback_head *work;
|
||||
unsigned long flags;
|
||||
|
||||
if (likely(!task->task_works))
|
||||
if (likely(!task_work_pending(task)))
|
||||
return NULL;
|
||||
/*
|
||||
* If cmpxchg() fails we continue without updating pprev.
|
||||
|
@ -15,6 +15,7 @@
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/compat.h>
|
||||
#include <linux/sched/deadline.h>
|
||||
#include <linux/task_work.h>
|
||||
|
||||
#include "posix-timers.h"
|
||||
|
||||
|
@ -60,7 +60,7 @@
|
||||
#include <linux/oom.h>
|
||||
#include <linux/lockdep.h>
|
||||
#include <linux/file.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/resume_user_mode.h>
|
||||
#include <linux/psi.h>
|
||||
#include <linux/seq_buf.h>
|
||||
#include "internal.h"
|
||||
|
@ -14,7 +14,6 @@
|
||||
#include <linux/file.h>
|
||||
#include <linux/mount.h>
|
||||
#include <linux/syscalls.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/personality.h>
|
||||
#include <linux/xattr.h>
|
||||
#include <linux/user_namespace.h>
|
||||
|
@ -25,7 +25,6 @@
|
||||
#include <linux/kd.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/kernel_read_file.h>
|
||||
#include <linux/tracehook.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/sched/signal.h>
|
||||
#include <linux/sched/task.h>
|
||||
|
Loading…
Reference in New Issue
Block a user