1#ifndef _LINUX_PTRACE_H
2#define _LINUX_PTRACE_H
3
4#include <linux/compiler.h>
5#include <linux/sched.h>
6#include <linux/err.h>
7#include <linux/bug.h>
8#include <uapi/linux/ptrace.h>
9
10
11
12
13
14
15
16
17
18#define PT_SEIZED 0x00010000
19#define PT_PTRACED 0x00000001
20#define PT_DTRACE 0x00000002
21#define PT_PTRACE_CAP 0x00000004
22
23#define PT_OPT_FLAG_SHIFT 3
24
25#define PT_EVENT_FLAG(event) (1 << (PT_OPT_FLAG_SHIFT + (event)))
26#define PT_TRACESYSGOOD PT_EVENT_FLAG(0)
27#define PT_TRACE_FORK PT_EVENT_FLAG(PTRACE_EVENT_FORK)
28#define PT_TRACE_VFORK PT_EVENT_FLAG(PTRACE_EVENT_VFORK)
29#define PT_TRACE_CLONE PT_EVENT_FLAG(PTRACE_EVENT_CLONE)
30#define PT_TRACE_EXEC PT_EVENT_FLAG(PTRACE_EVENT_EXEC)
31#define PT_TRACE_VFORK_DONE PT_EVENT_FLAG(PTRACE_EVENT_VFORK_DONE)
32#define PT_TRACE_EXIT PT_EVENT_FLAG(PTRACE_EVENT_EXIT)
33#define PT_TRACE_SECCOMP PT_EVENT_FLAG(PTRACE_EVENT_SECCOMP)
34
35#define PT_EXITKILL (PTRACE_O_EXITKILL << PT_OPT_FLAG_SHIFT)
36
37
38#define PT_SINGLESTEP_BIT 31
39#define PT_SINGLESTEP (1<<PT_SINGLESTEP_BIT)
40#define PT_BLOCKSTEP_BIT 30
41#define PT_BLOCKSTEP (1<<PT_BLOCKSTEP_BIT)
42
43extern long arch_ptrace(struct task_struct *child, long request,
44 unsigned long addr, unsigned long data);
45extern int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len);
46extern int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int len);
47extern void ptrace_disable(struct task_struct *);
48extern int ptrace_request(struct task_struct *child, long request,
49 unsigned long addr, unsigned long data);
50extern void ptrace_notify(int exit_code);
51extern void __ptrace_link(struct task_struct *child,
52 struct task_struct *new_parent);
53extern void __ptrace_unlink(struct task_struct *child);
54extern void exit_ptrace(struct task_struct *tracer);
55#define PTRACE_MODE_READ 0x01
56#define PTRACE_MODE_ATTACH 0x02
57#define PTRACE_MODE_NOAUDIT 0x04
58
59extern bool ptrace_may_access(struct task_struct *task, unsigned int mode);
60
61static inline int ptrace_reparented(struct task_struct *child)
62{
63 return !same_thread_group(child->real_parent, child->parent);
64}
65
66static inline void ptrace_unlink(struct task_struct *child)
67{
68 if (unlikely(child->ptrace))
69 __ptrace_unlink(child);
70}
71
72int generic_ptrace_peekdata(struct task_struct *tsk, unsigned long addr,
73 unsigned long data);
74int generic_ptrace_pokedata(struct task_struct *tsk, unsigned long addr,
75 unsigned long data);
76
77
78
79
80
81
82
83
84
85
86
87
88static inline struct task_struct *ptrace_parent(struct task_struct *task)
89{
90 if (unlikely(task->ptrace))
91 return rcu_dereference(task->parent);
92 return NULL;
93}
94
95
96
97
98
99
100
101
102
103
104static inline bool ptrace_event_enabled(struct task_struct *task, int event)
105{
106 return task->ptrace & PT_EVENT_FLAG(event);
107}
108
109
110
111
112
113
114
115
116
117
118
119static inline void ptrace_event(int event, unsigned long message)
120{
121 if (unlikely(ptrace_event_enabled(current, event))) {
122 current->ptrace_message = message;
123 ptrace_notify((event << 8) | SIGTRAP);
124 } else if (event == PTRACE_EVENT_EXEC) {
125
126 if ((current->ptrace & (PT_PTRACED|PT_SEIZED)) == PT_PTRACED)
127 send_sig(SIGTRAP, current, 0);
128 }
129}
130
131
132
133
134
135
136
137
138
139
140
141static inline void ptrace_init_task(struct task_struct *child, bool ptrace)
142{
143 INIT_LIST_HEAD(&child->ptrace_entry);
144 INIT_LIST_HEAD(&child->ptraced);
145#ifdef CONFIG_HAVE_HW_BREAKPOINT
146 atomic_set(&child->ptrace_bp_refcnt, 1);
147#endif
148 child->jobctl = 0;
149 child->ptrace = 0;
150 child->parent = child->real_parent;
151
152 if (unlikely(ptrace) && current->ptrace) {
153 child->ptrace = current->ptrace;
154 __ptrace_link(child, current->parent);
155
156 if (child->ptrace & PT_SEIZED)
157 task_set_jobctl_pending(child, JOBCTL_TRAP_STOP);
158 else
159 sigaddset(&child->pending.signal, SIGSTOP);
160
161 set_tsk_thread_flag(child, TIF_SIGPENDING);
162 }
163}
164
165
166
167
168
169
170
171static inline void ptrace_release_task(struct task_struct *task)
172{
173 BUG_ON(!list_empty(&task->ptraced));
174 ptrace_unlink(task);
175 BUG_ON(!list_empty(&task->ptrace_entry));
176}
177
178#ifndef force_successful_syscall_return
179
180
181
182
183
184
185
186
187
188
189
190#define force_successful_syscall_return() do { } while (0)
191#endif
192
193#ifndef is_syscall_success
194
195
196
197
198
199#define is_syscall_success(regs) (!IS_ERR_VALUE((unsigned long)(regs_return_value(regs))))
200#endif
201
202
203
204
205
206
207
208
209
210#ifndef arch_has_single_step
211
212
213
214
215
216
217
218
219
220#define arch_has_single_step() (0)
221
222
223
224
225
226
227
228
229
230
231static inline void user_enable_single_step(struct task_struct *task)
232{
233 BUG();
234}
235
236
237
238
239
240
241
242
243
244
245static inline void user_disable_single_step(struct task_struct *task)
246{
247}
248#else
249extern void user_enable_single_step(struct task_struct *);
250extern void user_disable_single_step(struct task_struct *);
251#endif
252
253#ifndef arch_has_block_step
254
255
256
257
258
259
260
261
262
263#define arch_has_block_step() (0)
264
265
266
267
268
269
270
271
272
273
274static inline void user_enable_block_step(struct task_struct *task)
275{
276 BUG();
277}
278#else
279extern void user_enable_block_step(struct task_struct *);
280#endif
281
282#ifdef ARCH_HAS_USER_SINGLE_STEP_INFO
283extern void user_single_step_siginfo(struct task_struct *tsk,
284 struct pt_regs *regs, siginfo_t *info);
285#else
286static inline void user_single_step_siginfo(struct task_struct *tsk,
287 struct pt_regs *regs, siginfo_t *info)
288{
289 memset(info, 0, sizeof(*info));
290 info->si_signo = SIGTRAP;
291}
292#endif
293
294#ifndef arch_ptrace_stop_needed
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309#define arch_ptrace_stop_needed(code, info) (0)
310#endif
311
312#ifndef arch_ptrace_stop
313
314
315
316
317
318
319
320
321
322
323
324
325
326#define arch_ptrace_stop(code, info) do { } while (0)
327#endif
328
329#ifndef current_pt_regs
330#define current_pt_regs() task_pt_regs(current)
331#endif
332
333#ifndef ptrace_signal_deliver
334#define ptrace_signal_deliver() ((void)0)
335#endif
336
337
338
339
340
341
342#ifndef signal_pt_regs
343#define signal_pt_regs() task_pt_regs(current)
344#endif
345
346#ifndef current_user_stack_pointer
347#define current_user_stack_pointer() user_stack_pointer(current_pt_regs())
348#endif
349
350extern int task_current_syscall(struct task_struct *target, long *callno,
351 unsigned long args[6], unsigned int maxargs,
352 unsigned long *sp, unsigned long *pc);
353
354#ifdef CONFIG_HAVE_HW_BREAKPOINT
355extern int ptrace_get_breakpoints(struct task_struct *tsk);
356extern void ptrace_put_breakpoints(struct task_struct *tsk);
357#else
358static inline void ptrace_put_breakpoints(struct task_struct *tsk) { }
359#endif
360
361#endif
362