History

ptrace: Migrate to use SYSCALL_TRACE flag

On architectures using the generic syscall entry code the architecture independent syscall work is moved to flags in thread_info::syscall_work. This removes architecture dependencies and frees up TIF bits. Define SYSCALL_WORK_SYSCALL_TRACE, use it in the generic entry code and convert the code which uses the TIF specific helper functions to use the new *_syscall_work() helpers which either resolve to the new mode for users of the generic entry code or to the TIF based functions for the other architectures.

Gabriel Krisman Bertazi committed 5 years ago

Commit 64c19ba1 parent 524666c7 files · +31 −25Browse files

Unified · Split

7 files
  1. include/asm-generic/syscall.h +8 −7
  2. include/linux/entry-common.h +6 −4
  3. include/linux/thread_info.h +2 −0
  4. include/linux/tracehook.h +9 −8
  5. kernel/entry/common.c +2 −2
  6. kernel/fork.c +1 −1
  7. kernel/ptrace.c +3 −3
include/asm-generic/syscall.h+8−7
@@ -43,7 +43,7 @@ int syscall_get_nr(struct task_struct *task, struct pt_regs *regs); · 42 unmodified lines
43 * @regs: task_pt_regs() of @task43 * @regs: task_pt_regs() of @task
44 *44 *
45 * It's only valid to call this when @task is stopped for system45 * It's only valid to call this when @task is stopped for system
46 * call exit tracing (due to TIF_SYSCALL_TRACE or TIF_SYSCALL_AUDIT),46 * call exit tracing (due to %SYSCALL_WORK_SYSCALL_TRACE or TIF_SYSCALL_AUDIT),
47 * after tracehook_report_syscall_entry() returned nonzero to prevent47 * after tracehook_report_syscall_entry() returned nonzero to prevent
48 * the system call from taking place.48 * the system call from taking place.
49 *49 *
@@ -63,7 +63,7 @@ void syscall_rollback(struct task_struct *task, struct pt_regs *regs); · 13 unmodified lines
63 * Returns 0 if the system call succeeded, or -ERRORCODE if it failed.63 * Returns 0 if the system call succeeded, or -ERRORCODE if it failed.
64 *64 *
65 * It's only valid to call this when @task is stopped for tracing on exit65 * It's only valid to call this when @task is stopped for tracing on exit
66 * from a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT.66 * from a system call, due to %SYSCALL_WORK_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT.
67 */67 */
68long syscall_get_error(struct task_struct *task, struct pt_regs *regs);68long syscall_get_error(struct task_struct *task, struct pt_regs *regs);
69 69
@@ -76,7 +76,7 @@ long syscall_get_error(struct task_struct *task, struct pt_regs *regs); · 6 unmodified lines
76 * This value is meaningless if syscall_get_error() returned nonzero.76 * This value is meaningless if syscall_get_error() returned nonzero.
77 *77 *
78 * It's only valid to call this when @task is stopped for tracing on exit78 * It's only valid to call this when @task is stopped for tracing on exit
79 * from a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT.79 * from a system call, due to %SYSCALL_WORK_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT.
80 */80 */
81long syscall_get_return_value(struct task_struct *task, struct pt_regs *regs);81long syscall_get_return_value(struct task_struct *task, struct pt_regs *regs);
82 82
@@ -93,7 +93,7 @@ long syscall_get_return_value(struct task_struct *task, struct pt_regs *regs); · 10 unmodified lines
93 * code; the user sees a failed system call with this errno code.93 * code; the user sees a failed system call with this errno code.
94 *94 *
95 * It's only valid to call this when @task is stopped for tracing on exit95 * It's only valid to call this when @task is stopped for tracing on exit
96 * from a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT.96 * from a system call, due to %SYSCALL_WORK_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT.
97 */97 */
98void syscall_set_return_value(struct task_struct *task, struct pt_regs *regs,98void syscall_set_return_value(struct task_struct *task, struct pt_regs *regs,
99 int error, long val);99 int error, long val);
@@ -108,7 +108,7 @@ void syscall_set_return_value(struct task_struct *task, struct pt_regs *regs, · 8 unmodified lines
108* @args[0], and so on.108* @args[0], and so on.
109 *109 *
110 * It's only valid to call this when @task is stopped for tracing on110 * It's only valid to call this when @task is stopped for tracing on
111 * entry to a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT.111 * entry to a system call, due to %SYSCALL_WORK_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT.
112 */112 */
113void syscall_get_arguments(struct task_struct *task, struct pt_regs *regs,113void syscall_get_arguments(struct task_struct *task, struct pt_regs *regs,
114 unsigned long *args);114 unsigned long *args);
@@ -123,7 +123,7 @@ void syscall_get_arguments(struct task_struct *task, struct pt_regs *regs, · 8 unmodified lines
123 * The first argument gets value @args[0], and so on.123 * The first argument gets value @args[0], and so on.
124 *124 *
125 * It's only valid to call this when @task is stopped for tracing on125 * It's only valid to call this when @task is stopped for tracing on
126 * entry to a system call, due to %TIF_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT.126 * entry to a system call, due to %SYSCALL_WORK_SYSCALL_TRACE or %TIF_SYSCALL_AUDIT.
127 */127 */
128void syscall_set_arguments(struct task_struct *task, struct pt_regs *regs,128void syscall_set_arguments(struct task_struct *task, struct pt_regs *regs,
129 const unsigned long *args);129 const unsigned long *args);
@@ -135,7 +135,8 @@ void syscall_set_arguments(struct task_struct *task, struct pt_regs *regs, · 5 unmodified lines
135 * Returns the AUDIT_ARCH_* based on the system call convention in use.135 * Returns the AUDIT_ARCH_* based on the system call convention in use.
136 *136 *
137 * It's only valid to call this when @task is stopped on entry to a system137 * It's only valid to call this when @task is stopped on entry to a system
138 * call, due to %TIF_SYSCALL_TRACE, %TIF_SYSCALL_AUDIT, or %SYSCALL_WORK_SECCOMP.138 * call, due to %SYSCALL_WORK_SYSCALL_TRACE, %TIF_SYSCALL_AUDIT, or
139 * %SYSCALL_WORK_SECCOMP.
139 *140 *
140 * Architectures which permit CONFIG_HAVE_ARCH_SECCOMP_FILTER must141 * Architectures which permit CONFIG_HAVE_ARCH_SECCOMP_FILTER must
141 * provide an implementation of this.142 * provide an implementation of this.
include/linux/entry-common.h+6−4
@@ -41,7 +41,7 @@ · 40 unmodified lines
41#endif41#endif
42 42
43#define SYSCALL_ENTER_WORK \43#define SYSCALL_ENTER_WORK \
44 (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \44 (_TIF_SYSCALL_AUDIT | \
45 _TIF_SYSCALL_EMU | \45 _TIF_SYSCALL_EMU | \
46 ARCH_SYSCALL_ENTER_WORK)46 ARCH_SYSCALL_ENTER_WORK)
47 47
@@ -53,12 +53,14 @@ · 5 unmodified lines
53#endif53#endif
54 54
55#define SYSCALL_EXIT_WORK \55#define SYSCALL_EXIT_WORK \
56 (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_AUDIT | \56 (_TIF_SYSCALL_AUDIT | \
57 ARCH_SYSCALL_EXIT_WORK)57 ARCH_SYSCALL_EXIT_WORK)
58 58
59#define SYSCALL_WORK_ENTER (SYSCALL_WORK_SECCOMP | \59#define SYSCALL_WORK_ENTER (SYSCALL_WORK_SECCOMP | \
60 SYSCALL_WORK_SYSCALL_TRACEPOINT)60 SYSCALL_WORK_SYSCALL_TRACEPOINT | \
61#define SYSCALL_WORK_EXIT (SYSCALL_WORK_SYSCALL_TRACEPOINT)61 SYSCALL_WORK_SYSCALL_TRACE)
62#define SYSCALL_WORK_EXIT (SYSCALL_WORK_SYSCALL_TRACEPOINT | \
63 SYSCALL_WORK_SYSCALL_TRACE)
62 64
63/*65/*
64 * TIF flags handled in exit_to_user_mode_loop()66 * TIF flags handled in exit_to_user_mode_loop()
include/linux/thread_info.h+2−0
@@ -38,10 +38,12 @@ enum { · 37 unmodified lines
38enum syscall_work_bit {38enum syscall_work_bit {
39 SYSCALL_WORK_BIT_SECCOMP,39 SYSCALL_WORK_BIT_SECCOMP,
40 SYSCALL_WORK_BIT_SYSCALL_TRACEPOINT,40 SYSCALL_WORK_BIT_SYSCALL_TRACEPOINT,
41 SYSCALL_WORK_BIT_SYSCALL_TRACE,
41};42};
42 43
43#define SYSCALL_WORK_SECCOMP BIT(SYSCALL_WORK_BIT_SECCOMP)44#define SYSCALL_WORK_SECCOMP BIT(SYSCALL_WORK_BIT_SECCOMP)
44#define SYSCALL_WORK_SYSCALL_TRACEPOINT BIT(SYSCALL_WORK_BIT_SYSCALL_TRACEPOINT)45#define SYSCALL_WORK_SYSCALL_TRACEPOINT BIT(SYSCALL_WORK_BIT_SYSCALL_TRACEPOINT)
46#define SYSCALL_WORK_SYSCALL_TRACE BIT(SYSCALL_WORK_BIT_SYSCALL_TRACE)
45 47
46#include <asm/thread_info.h>48#include <asm/thread_info.h>
47 49
include/linux/tracehook.h+9−8
@@ -83,11 +83,12 @@ static inline int ptrace_report_syscall(struct pt_regs *regs, · 82 unmodified lines
83 * tracehook_report_syscall_entry - task is about to attempt a system call83 * tracehook_report_syscall_entry - task is about to attempt a system call
84 * @regs: user register state of current task84 * @regs: user register state of current task
85 *85 *
86 * This will be called if %TIF_SYSCALL_TRACE or %TIF_SYSCALL_EMU have been set,86 * This will be called if %SYSCALL_WORK_SYSCALL_TRACE or
87 * when the current task has just entered the kernel for a system call.87 * %TIF_SYSCALL_EMU have been set, when the current task has just
88 * Full user register state is available here. Changing the values88 * entered the kernel for a system call. Full user register state is
89 * in @regs can affect the system call number and arguments to be tried.89 * available here. Changing the values in @regs can affect the system
90 * It is safe to block here, preventing the system call from beginning.90 * call number and arguments to be tried. It is safe to block here,
91 * preventing the system call from beginning.
91 *92 *
92 * Returns zero normally, or nonzero if the calling arch code should abort93 * Returns zero normally, or nonzero if the calling arch code should abort
93 * the system call. That must prevent normal entry so no system call is94 * the system call. That must prevent normal entry so no system call is
@@ -109,15 +110,15 @@ static inline __must_check int tracehook_report_syscall_entry( · 15 unmodified lines
109 * @regs: user register state of current task110 * @regs: user register state of current task
110 * @step: nonzero if simulating single-step or block-step111 * @step: nonzero if simulating single-step or block-step
111 *112 *
112 * This will be called if %TIF_SYSCALL_TRACE has been set, when the113 * This will be called if %SYSCALL_WORK_SYSCALL_TRACE has been set, when
113 * current task has just finished an attempted system call. Full114 * the current task has just finished an attempted system call. Full
114 * user register state is available here. It is safe to block here,115 * user register state is available here. It is safe to block here,
115 * preventing signals from being processed.116 * preventing signals from being processed.
116 *117 *
117 * If @step is nonzero, this report is also in lieu of the normal118 * If @step is nonzero, this report is also in lieu of the normal
118 * trap that would follow the system call instruction because119 * trap that would follow the system call instruction because
119 * user_enable_block_step() or user_enable_single_step() was used.120 * user_enable_block_step() or user_enable_single_step() was used.
120 * In this case, %TIF_SYSCALL_TRACE might not be set.121 * In this case, %SYSCALL_WORK_SYSCALL_TRACE might not be set.
121 *122 *
122 * Called without locks, just before checking for pending signals.123 * Called without locks, just before checking for pending signals.
123 */124 */
kernel/entry/common.c+2−2
@@ -47,7 +47,7 @@ static long syscall_trace_enter(struct pt_regs *regs, long syscall, · 46 unmodified lines
47 long ret = 0;47 long ret = 0;
48 48
49 /* Handle ptrace */49 /* Handle ptrace */
50 if (ti_work & (_TIF_SYSCALL_TRACE | _TIF_SYSCALL_EMU)) {50 if (work & SYSCALL_WORK_SYSCALL_TRACE || ti_work & _TIF_SYSCALL_EMU) {
51 ret = arch_syscall_enter_tracehook(regs);51 ret = arch_syscall_enter_tracehook(regs);
52 if (ret || (ti_work & _TIF_SYSCALL_EMU))52 if (ret || (ti_work & _TIF_SYSCALL_EMU))
53 return -1L;53 return -1L;
@@ -237,7 +237,7 @@ static void syscall_exit_work(struct pt_regs *regs, unsigned long ti_work, · 183 unmodified lines
237 trace_sys_exit(regs, syscall_get_return_value(current, regs));237 trace_sys_exit(regs, syscall_get_return_value(current, regs));
238 238
239 step = report_single_step(ti_work);239 step = report_single_step(ti_work);
240 if (step || ti_work & _TIF_SYSCALL_TRACE)240 if (step || work & SYSCALL_WORK_SYSCALL_TRACE)
241 arch_syscall_exit_tracehook(regs, step);241 arch_syscall_exit_tracehook(regs, step);
242}242}
243 243
kernel/fork.c+1−1
@@ -2158,7 +2158,7 @@ static __latent_entropy struct task_struct *copy_process( · 2157 unmodified lines
2158 * child regardless of CLONE_PTRACE.2158 * child regardless of CLONE_PTRACE.
2159 */2159 */
2160 user_disable_single_step(p);2160 user_disable_single_step(p);
2161 clear_tsk_thread_flag(p, TIF_SYSCALL_TRACE);2161 clear_task_syscall_work(p, SYSCALL_TRACE);
2162#ifdef TIF_SYSCALL_EMU2162#ifdef TIF_SYSCALL_EMU
2163 clear_tsk_thread_flag(p, TIF_SYSCALL_EMU);2163 clear_tsk_thread_flag(p, TIF_SYSCALL_EMU);
2164#endif2164#endif
kernel/ptrace.c+3−3
@@ -117,7 +117,7 @@ void __ptrace_unlink(struct task_struct *child) · 116 unmodified lines
117 const struct cred *old_cred;117 const struct cred *old_cred;
118 BUG_ON(!child->ptrace);118 BUG_ON(!child->ptrace);
119 119
120 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);120 clear_task_syscall_work(child, SYSCALL_TRACE);
121#ifdef TIF_SYSCALL_EMU121#ifdef TIF_SYSCALL_EMU
122 clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);122 clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
123#endif123#endif
@@ -812,9 +812,9 @@ static int ptrace_resume(struct task_struct *child, long request, · 688 unmodified lines
812 return -EIO;812 return -EIO;
813 813
814 if (request == PTRACE_SYSCALL)814 if (request == PTRACE_SYSCALL)
815 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);815 set_task_syscall_work(child, SYSCALL_TRACE);
816 else816 else
817 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);817 clear_task_syscall_work(child, SYSCALL_TRACE);
818 818
819#ifdef TIF_SYSCALL_EMU819#ifdef TIF_SYSCALL_EMU
820 if (request == PTRACE_SYSEMU || request == PTRACE_SYSEMU_SINGLESTEP)820 if (request == PTRACE_SYSEMU || request == PTRACE_SYSEMU_SINGLESTEP)

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t