1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18#include <linux/regset.h>
19#include <linux/tracehook.h>
20#include <linux/audit.h>
21#include <linux/context_tracking.h>
22#include <linux/syscalls.h>
23
24#include <asm/switch_to.h>
25#include <asm/asm-prototypes.h>
26#include <asm/debug.h>
27
28#define CREATE_TRACE_POINTS
29#include <trace/events/syscalls.h>
30
31#include "ptrace-decl.h"
32
33
34
35
36
37
38void ptrace_disable(struct task_struct *child)
39{
40
41 user_disable_single_step(child);
42}
43
44long arch_ptrace(struct task_struct *child, long request,
45 unsigned long addr, unsigned long data)
46{
47 int ret = -EPERM;
48 void __user *datavp = (void __user *) data;
49 unsigned long __user *datalp = datavp;
50
51 switch (request) {
52
53 case PTRACE_PEEKUSR: {
54 unsigned long index, tmp;
55
56 ret = -EIO;
57
58 index = addr / sizeof(long);
59 if ((addr & (sizeof(long) - 1)) || !child->thread.regs)
60 break;
61
62 if (index < PT_FPR0)
63 ret = ptrace_get_reg(child, (int) index, &tmp);
64 else
65 ret = ptrace_get_fpr(child, index, &tmp);
66
67 if (ret)
68 break;
69 ret = put_user(tmp, datalp);
70 break;
71 }
72
73
74 case PTRACE_POKEUSR: {
75 unsigned long index;
76
77 ret = -EIO;
78
79 index = addr / sizeof(long);
80 if ((addr & (sizeof(long) - 1)) || !child->thread.regs)
81 break;
82
83 if (index < PT_FPR0)
84 ret = ptrace_put_reg(child, index, data);
85 else
86 ret = ptrace_put_fpr(child, index, data);
87 break;
88 }
89
90 case PPC_PTRACE_GETHWDBGINFO: {
91 struct ppc_debug_info dbginfo;
92
93 ppc_gethwdinfo(&dbginfo);
94
95 if (copy_to_user(datavp, &dbginfo,
96 sizeof(struct ppc_debug_info)))
97 return -EFAULT;
98 return 0;
99 }
100
101 case PPC_PTRACE_SETHWDEBUG: {
102 struct ppc_hw_breakpoint bp_info;
103
104 if (copy_from_user(&bp_info, datavp,
105 sizeof(struct ppc_hw_breakpoint)))
106 return -EFAULT;
107 return ppc_set_hwdebug(child, &bp_info);
108 }
109
110 case PPC_PTRACE_DELHWDEBUG: {
111 ret = ppc_del_hwdebug(child, data);
112 break;
113 }
114
115 case PTRACE_GET_DEBUGREG:
116 ret = ptrace_get_debugreg(child, addr, datalp);
117 break;
118
119 case PTRACE_SET_DEBUGREG:
120 ret = ptrace_set_debugreg(child, addr, data);
121 break;
122
123#ifdef CONFIG_PPC64
124 case PTRACE_GETREGS64:
125#endif
126 case PTRACE_GETREGS:
127 return copy_regset_to_user(child, &user_ppc_native_view,
128 REGSET_GPR,
129 0, sizeof(struct user_pt_regs),
130 datavp);
131
132#ifdef CONFIG_PPC64
133 case PTRACE_SETREGS64:
134#endif
135 case PTRACE_SETREGS:
136 return copy_regset_from_user(child, &user_ppc_native_view,
137 REGSET_GPR,
138 0, sizeof(struct user_pt_regs),
139 datavp);
140
141 case PTRACE_GETFPREGS:
142 return copy_regset_to_user(child, &user_ppc_native_view,
143 REGSET_FPR,
144 0, sizeof(elf_fpregset_t),
145 datavp);
146
147 case PTRACE_SETFPREGS:
148 return copy_regset_from_user(child, &user_ppc_native_view,
149 REGSET_FPR,
150 0, sizeof(elf_fpregset_t),
151 datavp);
152
153#ifdef CONFIG_ALTIVEC
154 case PTRACE_GETVRREGS:
155 return copy_regset_to_user(child, &user_ppc_native_view,
156 REGSET_VMX,
157 0, (33 * sizeof(vector128) +
158 sizeof(u32)),
159 datavp);
160
161 case PTRACE_SETVRREGS:
162 return copy_regset_from_user(child, &user_ppc_native_view,
163 REGSET_VMX,
164 0, (33 * sizeof(vector128) +
165 sizeof(u32)),
166 datavp);
167#endif
168#ifdef CONFIG_VSX
169 case PTRACE_GETVSRREGS:
170 return copy_regset_to_user(child, &user_ppc_native_view,
171 REGSET_VSX,
172 0, 32 * sizeof(double),
173 datavp);
174
175 case PTRACE_SETVSRREGS:
176 return copy_regset_from_user(child, &user_ppc_native_view,
177 REGSET_VSX,
178 0, 32 * sizeof(double),
179 datavp);
180#endif
181#ifdef CONFIG_SPE
182 case PTRACE_GETEVRREGS:
183
184 return copy_regset_to_user(child, &user_ppc_native_view,
185 REGSET_SPE, 0, 35 * sizeof(u32),
186 datavp);
187
188 case PTRACE_SETEVRREGS:
189
190 return copy_regset_from_user(child, &user_ppc_native_view,
191 REGSET_SPE, 0, 35 * sizeof(u32),
192 datavp);
193#endif
194
195 default:
196 ret = ptrace_request(child, request, addr, data);
197 break;
198 }
199 return ret;
200}
201
202#ifdef CONFIG_SECCOMP
203static int do_seccomp(struct pt_regs *regs)
204{
205 if (!test_thread_flag(TIF_SECCOMP))
206 return 0;
207
208
209
210
211
212
213
214 regs->gpr[3] = -ENOSYS;
215
216
217
218
219
220
221
222 if (__secure_computing(NULL))
223 return -1;
224
225
226
227
228
229
230
231
232 regs->gpr[3] = regs->orig_gpr3;
233
234 return 0;
235}
236#else
237static inline int do_seccomp(struct pt_regs *regs) { return 0; }
238#endif
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259long do_syscall_trace_enter(struct pt_regs *regs)
260{
261 u32 flags;
262
263 flags = READ_ONCE(current_thread_info()->flags) &
264 (_TIF_SYSCALL_EMU | _TIF_SYSCALL_TRACE);
265
266 if (flags) {
267 int rc = tracehook_report_syscall_entry(regs);
268
269 if (unlikely(flags & _TIF_SYSCALL_EMU)) {
270
271
272
273
274
275
276
277
278
279
280 return -1;
281 }
282
283 if (rc) {
284
285
286
287
288
289
290 goto skip;
291 }
292 }
293
294
295 if (do_seccomp(regs))
296 return -1;
297
298
299 if (regs->gpr[0] >= NR_syscalls)
300 goto skip;
301
302 if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
303 trace_sys_enter(regs, regs->gpr[0]);
304
305 if (!is_32bit_task())
306 audit_syscall_entry(regs->gpr[0], regs->gpr[3], regs->gpr[4],
307 regs->gpr[5], regs->gpr[6]);
308 else
309 audit_syscall_entry(regs->gpr[0],
310 regs->gpr[3] & 0xffffffff,
311 regs->gpr[4] & 0xffffffff,
312 regs->gpr[5] & 0xffffffff,
313 regs->gpr[6] & 0xffffffff);
314
315
316 return regs->gpr[0];
317
318skip:
319
320
321
322
323 regs->gpr[3] = -ENOSYS;
324 return -1;
325}
326
327void do_syscall_trace_leave(struct pt_regs *regs)
328{
329 int step;
330
331 audit_syscall_exit(regs);
332
333 if (unlikely(test_thread_flag(TIF_SYSCALL_TRACEPOINT)))
334 trace_sys_exit(regs, regs->result);
335
336 step = test_thread_flag(TIF_SINGLESTEP);
337 if (step || test_thread_flag(TIF_SYSCALL_TRACE))
338 tracehook_report_syscall_exit(regs, step);
339}
340
341void __init pt_regs_check(void);
342
343
344
345
346
347void __init pt_regs_check(void)
348{
349 BUILD_BUG_ON(offsetof(struct pt_regs, gpr) !=
350 offsetof(struct user_pt_regs, gpr));
351 BUILD_BUG_ON(offsetof(struct pt_regs, nip) !=
352 offsetof(struct user_pt_regs, nip));
353 BUILD_BUG_ON(offsetof(struct pt_regs, msr) !=
354 offsetof(struct user_pt_regs, msr));
355 BUILD_BUG_ON(offsetof(struct pt_regs, orig_gpr3) !=
356 offsetof(struct user_pt_regs, orig_gpr3));
357 BUILD_BUG_ON(offsetof(struct pt_regs, ctr) !=
358 offsetof(struct user_pt_regs, ctr));
359 BUILD_BUG_ON(offsetof(struct pt_regs, link) !=
360 offsetof(struct user_pt_regs, link));
361 BUILD_BUG_ON(offsetof(struct pt_regs, xer) !=
362 offsetof(struct user_pt_regs, xer));
363 BUILD_BUG_ON(offsetof(struct pt_regs, ccr) !=
364 offsetof(struct user_pt_regs, ccr));
365#ifdef __powerpc64__
366 BUILD_BUG_ON(offsetof(struct pt_regs, softe) !=
367 offsetof(struct user_pt_regs, softe));
368#else
369 BUILD_BUG_ON(offsetof(struct pt_regs, mq) !=
370 offsetof(struct user_pt_regs, mq));
371#endif
372 BUILD_BUG_ON(offsetof(struct pt_regs, trap) !=
373 offsetof(struct user_pt_regs, trap));
374 BUILD_BUG_ON(offsetof(struct pt_regs, dar) !=
375 offsetof(struct user_pt_regs, dar));
376 BUILD_BUG_ON(offsetof(struct pt_regs, dear) !=
377 offsetof(struct user_pt_regs, dar));
378 BUILD_BUG_ON(offsetof(struct pt_regs, dsisr) !=
379 offsetof(struct user_pt_regs, dsisr));
380 BUILD_BUG_ON(offsetof(struct pt_regs, esr) !=
381 offsetof(struct user_pt_regs, dsisr));
382 BUILD_BUG_ON(offsetof(struct pt_regs, result) !=
383 offsetof(struct user_pt_regs, result));
384
385 BUILD_BUG_ON(sizeof(struct user_pt_regs) > sizeof(struct pt_regs));
386
387
388 #define CHECK_REG(_pt, _reg) \
389 BUILD_BUG_ON(_pt != (offsetof(struct user_pt_regs, _reg) / \
390 sizeof(unsigned long)));
391
392 CHECK_REG(PT_R0, gpr[0]);
393 CHECK_REG(PT_R1, gpr[1]);
394 CHECK_REG(PT_R2, gpr[2]);
395 CHECK_REG(PT_R3, gpr[3]);
396 CHECK_REG(PT_R4, gpr[4]);
397 CHECK_REG(PT_R5, gpr[5]);
398 CHECK_REG(PT_R6, gpr[6]);
399 CHECK_REG(PT_R7, gpr[7]);
400 CHECK_REG(PT_R8, gpr[8]);
401 CHECK_REG(PT_R9, gpr[9]);
402 CHECK_REG(PT_R10, gpr[10]);
403 CHECK_REG(PT_R11, gpr[11]);
404 CHECK_REG(PT_R12, gpr[12]);
405 CHECK_REG(PT_R13, gpr[13]);
406 CHECK_REG(PT_R14, gpr[14]);
407 CHECK_REG(PT_R15, gpr[15]);
408 CHECK_REG(PT_R16, gpr[16]);
409 CHECK_REG(PT_R17, gpr[17]);
410 CHECK_REG(PT_R18, gpr[18]);
411 CHECK_REG(PT_R19, gpr[19]);
412 CHECK_REG(PT_R20, gpr[20]);
413 CHECK_REG(PT_R21, gpr[21]);
414 CHECK_REG(PT_R22, gpr[22]);
415 CHECK_REG(PT_R23, gpr[23]);
416 CHECK_REG(PT_R24, gpr[24]);
417 CHECK_REG(PT_R25, gpr[25]);
418 CHECK_REG(PT_R26, gpr[26]);
419 CHECK_REG(PT_R27, gpr[27]);
420 CHECK_REG(PT_R28, gpr[28]);
421 CHECK_REG(PT_R29, gpr[29]);
422 CHECK_REG(PT_R30, gpr[30]);
423 CHECK_REG(PT_R31, gpr[31]);
424 CHECK_REG(PT_NIP, nip);
425 CHECK_REG(PT_MSR, msr);
426 CHECK_REG(PT_ORIG_R3, orig_gpr3);
427 CHECK_REG(PT_CTR, ctr);
428 CHECK_REG(PT_LNK, link);
429 CHECK_REG(PT_XER, xer);
430 CHECK_REG(PT_CCR, ccr);
431#ifdef CONFIG_PPC64
432 CHECK_REG(PT_SOFTE, softe);
433#else
434 CHECK_REG(PT_MQ, mq);
435#endif
436 CHECK_REG(PT_TRAP, trap);
437 CHECK_REG(PT_DAR, dar);
438 CHECK_REG(PT_DSISR, dsisr);
439 CHECK_REG(PT_RESULT, result);
440 #undef CHECK_REG
441
442 BUILD_BUG_ON(PT_REGS_COUNT != sizeof(struct user_pt_regs) / sizeof(unsigned long));
443
444
445
446
447
448 BUILD_BUG_ON(PT_DSCR < sizeof(struct user_pt_regs) / sizeof(unsigned long));
449}
450