This source file includes following definitions.
- get_task
- get_reg
- put_reg
- get_long
- put_long
- find_extend_vma
- read_long
- write_long
- read_int
- write_int
- ptrace_set_bpt
- ptrace_cancel_bpt
- sys_ptrace
- syscall_trace
1
2
3
4
5
6
7 #include <linux/head.h>
8 #include <linux/kernel.h>
9 #include <linux/sched.h>
10 #include <linux/mm.h>
11 #include <linux/errno.h>
12 #include <linux/ptrace.h>
13 #include <linux/user.h>
14 #include <linux/debugreg.h>
15
16 #include <asm/segment.h>
17 #include <asm/pgtable.h>
18 #include <asm/system.h>
19
20 #undef DEBUG
21
22 #ifdef DEBUG
23
24 enum {
25 DBG_MEM = (1<<0),
26 DBG_BPT = (1<<1),
27 DBG_MEM_ALL = (1<<2)
28 };
29
30 int debug_mask = DBG_BPT;
31
32 # define DBG(fac,args) {if ((fac) & debug_mask) printk args;}
33
34 #else
35 # define DBG(fac,args)
36 #endif
37
38 #define BREAKINST 0x00000080
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 #define PT_REG(reg) (PAGE_SIZE - sizeof(struct pt_regs) \
71 + (long)&((struct pt_regs *)0)->reg)
72 #define SW_REG(reg) (PAGE_SIZE - sizeof(struct pt_regs) \
73 - sizeof(struct switch_stack) \
74 + (long)&((struct switch_stack *)0)->reg)
75
76
77
78
79
80
81
82 enum {
83 REG_R0 = 0, REG_F0 = 32, REG_PC = 64
84 };
85
86 static unsigned short regoff[] = {
87 PT_REG( r0), PT_REG( r1), PT_REG( r2), PT_REG( r3),
88 PT_REG( r4), PT_REG( r5), PT_REG( r6), PT_REG( r7),
89 PT_REG( r8), SW_REG( r9), SW_REG( r10), SW_REG( r11),
90 SW_REG( r12), SW_REG( r13), SW_REG( r14), SW_REG( r15),
91 PT_REG( r16), PT_REG( r17), PT_REG( r18), PT_REG( r19),
92 PT_REG( r20), PT_REG( r21), PT_REG( r22), PT_REG( r23),
93 PT_REG( r24), PT_REG( r25), PT_REG( r26), PT_REG( r27),
94 PT_REG( r28), PT_REG( gp), -1, -1,
95 SW_REG(fp[ 0]), SW_REG(fp[ 1]), SW_REG(fp[ 2]), SW_REG(fp[ 3]),
96 SW_REG(fp[ 4]), SW_REG(fp[ 5]), SW_REG(fp[ 6]), SW_REG(fp[ 7]),
97 SW_REG(fp[ 8]), SW_REG(fp[ 9]), SW_REG(fp[10]), SW_REG(fp[11]),
98 SW_REG(fp[12]), SW_REG(fp[13]), SW_REG(fp[14]), SW_REG(fp[15]),
99 SW_REG(fp[16]), SW_REG(fp[17]), SW_REG(fp[18]), SW_REG(fp[19]),
100 SW_REG(fp[20]), SW_REG(fp[21]), SW_REG(fp[22]), SW_REG(fp[23]),
101 SW_REG(fp[24]), SW_REG(fp[25]), SW_REG(fp[26]), SW_REG(fp[27]),
102 SW_REG(fp[28]), SW_REG(fp[29]), SW_REG(fp[30]), SW_REG(fp[31]),
103 PT_REG( pc)
104 };
105
106 static long zero;
107
108
109
110 static inline struct task_struct * get_task(int pid)
111 {
112 int i;
113
114 for (i = 1; i < NR_TASKS; i++) {
115 if (task[i] != NULL && (task[i]->pid == pid))
116 return task[i];
117 }
118 return NULL;
119 }
120
121
122
123
124 static inline long get_reg(struct task_struct * task, long regno)
125 {
126 long *addr;
127
128 if (regno == 30) {
129 addr = &task->tss.usp;
130 } else if (regno == 31) {
131 zero = 0;
132 addr = &zero;
133 } else {
134 addr = (long *) (task->kernel_stack_page + regoff[regno]);
135 }
136 return *addr;
137 }
138
139
140
141
142 static inline int put_reg(struct task_struct *task, long regno, long data)
143 {
144 long *addr, zero;
145
146 if (regno == 30) {
147 addr = &task->tss.usp;
148 } else if (regno == 31) {
149 addr = &zero;
150 } else {
151 addr = (long *) (task->kernel_stack_page + regoff[regno]);
152 }
153 *addr = data;
154 return 0;
155 }
156
157
158
159
160
161
162
163 static unsigned long get_long(struct task_struct * tsk,
164 struct vm_area_struct * vma, unsigned long addr)
165 {
166 pgd_t * pgdir;
167 pmd_t * pgmiddle;
168 pte_t * pgtable;
169 unsigned long page;
170
171 DBG(DBG_MEM_ALL, ("getting long at 0x%lx\n", addr));
172 repeat:
173 pgdir = pgd_offset(vma->vm_mm, addr);
174 if (pgd_none(*pgdir)) {
175 do_no_page(tsk, vma, addr, 0);
176 goto repeat;
177 }
178 if (pgd_bad(*pgdir)) {
179 printk("ptrace: bad page directory %08lx\n", pgd_val(*pgdir));
180 pgd_clear(pgdir);
181 return 0;
182 }
183 pgmiddle = pmd_offset(pgdir, addr);
184 if (pmd_none(*pgmiddle)) {
185 do_no_page(tsk, vma, addr, 0);
186 goto repeat;
187 }
188 if (pmd_bad(*pgmiddle)) {
189 printk("ptrace: bad page middle %08lx\n", pmd_val(*pgmiddle));
190 pmd_clear(pgmiddle);
191 return 0;
192 }
193 pgtable = pte_offset(pgmiddle, addr);
194 if (!pte_present(*pgtable)) {
195 do_no_page(tsk, vma, addr, 0);
196 goto repeat;
197 }
198 page = pte_page(*pgtable);
199
200 if (page >= high_memory)
201 return 0;
202 page += addr & ~PAGE_MASK;
203 return *(unsigned long *) page;
204 }
205
206
207
208
209
210
211
212
213
214
215 static void put_long(struct task_struct * tsk, struct vm_area_struct * vma,
216 unsigned long addr, unsigned long data)
217 {
218 pgd_t *pgdir;
219 pmd_t *pgmiddle;
220 pte_t *pgtable;
221 unsigned long page;
222
223 repeat:
224 pgdir = pgd_offset(vma->vm_mm, addr);
225 if (!pgd_present(*pgdir)) {
226 do_no_page(tsk, vma, addr, 1);
227 goto repeat;
228 }
229 if (pgd_bad(*pgdir)) {
230 printk("ptrace: bad page directory %08lx\n", pgd_val(*pgdir));
231 pgd_clear(pgdir);
232 return;
233 }
234 pgmiddle = pmd_offset(pgdir, addr);
235 if (pmd_none(*pgmiddle)) {
236 do_no_page(tsk, vma, addr, 1);
237 goto repeat;
238 }
239 if (pmd_bad(*pgmiddle)) {
240 printk("ptrace: bad page middle %08lx\n", pmd_val(*pgmiddle));
241 pmd_clear(pgmiddle);
242 return;
243 }
244 pgtable = pte_offset(pgmiddle, addr);
245 if (!pte_present(*pgtable)) {
246 do_no_page(tsk, vma, addr, 1);
247 goto repeat;
248 }
249 page = pte_page(*pgtable);
250 if (!pte_write(*pgtable)) {
251 do_wp_page(tsk, vma, addr, 1);
252 goto repeat;
253 }
254
255 if (page < high_memory)
256 *(unsigned long *) (page + (addr & ~PAGE_MASK)) = data;
257
258
259 set_pte(pgtable, pte_mkdirty(mk_pte(page, vma->vm_page_prot)));
260 invalidate();
261 }
262
263 static struct vm_area_struct * find_extend_vma(struct task_struct * tsk,
264 unsigned long addr)
265 {
266 struct vm_area_struct * vma;
267
268 addr &= PAGE_MASK;
269 vma = find_vma(tsk,addr);
270 if (!vma)
271 return NULL;
272 if (vma->vm_start <= addr)
273 return vma;
274 if (!(vma->vm_flags & VM_GROWSDOWN))
275 return NULL;
276 if (vma->vm_end - addr > tsk->rlim[RLIMIT_STACK].rlim_cur)
277 return NULL;
278 vma->vm_offset -= vma->vm_start - addr;
279 vma->vm_start = addr;
280 return vma;
281 }
282
283
284
285
286
287 static int read_long(struct task_struct * tsk, unsigned long addr,
288 unsigned long * result)
289 {
290 struct vm_area_struct * vma = find_extend_vma(tsk, addr);
291
292 DBG(DBG_MEM_ALL, ("in read_long\n"));
293 if (!vma) {
294 printk("Unable to find vma for addr 0x%lx\n",addr);
295 return -EIO;
296 }
297 if ((addr & ~PAGE_MASK) > (PAGE_SIZE - sizeof(long))) {
298 struct vm_area_struct * vma_high = vma;
299 unsigned long low, align;
300
301 if (addr + sizeof(long) >= vma->vm_end) {
302 vma_high = vma->vm_next;
303 if (!vma_high || vma_high->vm_start != vma->vm_end)
304 return -EIO;
305 }
306 align = addr & (sizeof(long) - 1);
307 addr -= align;
308 low = get_long(tsk, vma, addr);
309 if (align) {
310 unsigned long high;
311
312 high = get_long(tsk, vma_high, addr + sizeof(long));
313 low >>= align * 8;
314 low |= high << (64 - align * 8);
315 }
316 *result = low;
317 } else {
318 long l = get_long(tsk, vma, addr);
319
320 DBG(DBG_MEM_ALL, ("value is 0x%lx\n", l));
321 *result = l;
322 }
323 return 0;
324 }
325
326
327
328
329
330 static int write_long(struct task_struct * tsk, unsigned long addr,
331 unsigned long data)
332 {
333 struct vm_area_struct * vma = find_extend_vma(tsk, addr);
334
335 if (!vma)
336 return -EIO;
337 if ((addr & ~PAGE_MASK) > PAGE_SIZE-sizeof(long)) {
338 unsigned long low, high, align;
339 struct vm_area_struct * vma_high = vma;
340
341 if (addr + sizeof(long) >= vma->vm_end) {
342 vma_high = vma->vm_next;
343 if (!vma_high || vma_high->vm_start != vma->vm_end)
344 return -EIO;
345 }
346 align = addr & (sizeof(long) - 1);
347 addr -= align;
348 low = get_long(tsk, vma, addr);
349 high = get_long(tsk, vma_high, addr + sizeof(long));
350 low &= ~0UL >> (64 - align * 8);
351 high &= ~0UL << (align * 8);
352 low |= data << (align * 8);
353 high |= data >> (64 - align * 8);
354 put_long(tsk, vma, addr, low);
355 put_long(tsk, vma_high, addr + sizeof(long), high);
356 } else
357 put_long(tsk, vma, addr, data);
358 return 0;
359 }
360
361
362
363
364 static int read_int(struct task_struct * tsk, unsigned long addr,
365 unsigned int *data)
366 {
367 unsigned long l, align;
368 int res;
369
370 align = addr & 0x7;
371 addr &= ~0x7;
372
373 res = read_long(tsk, addr, &l);
374 if (res < 0)
375 return res;
376
377 if (align == 0) {
378 *data = l;
379 } else {
380 *data = l >> 32;
381 }
382 return 0;
383 }
384
385
386
387
388
389
390
391 static int write_int(struct task_struct * tsk, unsigned long addr,
392 unsigned int data)
393 {
394 unsigned long l, align;
395 int res;
396
397 align = addr & 0x7;
398 addr &= ~0x7;
399
400 res = read_long(tsk, addr, &l);
401 if (res < 0)
402 return res;
403
404 if (align == 0) {
405 l = (l & 0xffffffff00000000UL) | ((unsigned long) data << 0);
406 } else {
407 l = (l & 0x00000000ffffffffUL) | ((unsigned long) data << 32);
408 }
409 return write_long(tsk, addr, l);
410 }
411
412
413
414
415 int ptrace_set_bpt(struct task_struct * child)
416 {
417 int displ, i, res, reg_b, nsaved = 0;
418 u32 insn, op_code;
419 unsigned long pc;
420
421 pc = get_reg(child, REG_PC);
422 res = read_int(child, pc, &insn);
423 if (res < 0)
424 return res;
425
426 op_code = insn >> 26;
427 if (op_code >= 0x30) {
428
429
430
431
432
433
434
435
436 displ = ((s32)(insn << 11)) >> 9;
437 child->debugreg[nsaved++] = pc + 4;
438 if (displ)
439 child->debugreg[nsaved++] = pc + 4 + displ;
440 DBG(DBG_BPT, ("execing branch\n"));
441 } else if (op_code == 0x1a) {
442 reg_b = (insn >> 16) & 0x1f;
443 child->debugreg[nsaved++] = get_reg(child, reg_b);
444 DBG(DBG_BPT, ("execing jump\n"));
445 } else {
446 child->debugreg[nsaved++] = pc + 4;
447 DBG(DBG_BPT, ("execing normal insn\n"));
448 }
449
450
451 for (i = 0; i < nsaved; ++i) {
452 res = read_int(child, child->debugreg[i], &insn);
453 if (res < 0)
454 return res;
455 child->debugreg[i + 2] = insn;
456 DBG(DBG_BPT, (" -> next_pc=%lx\n", child->debugreg[i]));
457 res = write_int(child, child->debugreg[i], BREAKINST);
458 if (res < 0)
459 return res;
460 }
461 child->debugreg[4] = nsaved;
462 return 0;
463 }
464
465
466
467
468
469 int ptrace_cancel_bpt(struct task_struct * child)
470 {
471 int i, nsaved = child->debugreg[4];
472
473 child->debugreg[4] = 0;
474
475 if (nsaved > 2) {
476 printk("ptrace_cancel_bpt: bogus nsaved: %d!\n", nsaved);
477 nsaved = 2;
478 }
479
480 for (i = 0; i < nsaved; ++i) {
481 write_int(child, child->debugreg[i], child->debugreg[i + 2]);
482 }
483 return (nsaved != 0);
484 }
485
486 asmlinkage long sys_ptrace(long request, long pid, long addr, long data,
487 int a4, int a5, struct pt_regs regs)
488 {
489 struct task_struct *child;
490 struct user * dummy;
491
492 dummy = NULL;
493
494 DBG(DBG_MEM, ("request=%ld pid=%ld addr=0x%lx data=0x%lx\n",
495 request, pid, addr, data));
496 if (request == PTRACE_TRACEME) {
497
498 if (current->flags & PF_PTRACED)
499 return -EPERM;
500
501 current->flags |= PF_PTRACED;
502 return 0;
503 }
504 if (pid == 1)
505 return -EPERM;
506 if (!(child = get_task(pid)))
507 return -ESRCH;
508 if (request == PTRACE_ATTACH) {
509 if (child == current)
510 return -EPERM;
511 if ((!child->dumpable ||
512 (current->uid != child->euid) ||
513 (current->uid != child->uid) ||
514 (current->gid != child->egid) ||
515 (current->gid != child->gid)) && !suser())
516 return -EPERM;
517
518 if (child->flags & PF_PTRACED)
519 return -EPERM;
520 child->flags |= PF_PTRACED;
521 if (child->p_pptr != current) {
522 REMOVE_LINKS(child);
523 child->p_pptr = current;
524 SET_LINKS(child);
525 }
526 send_sig(SIGSTOP, child, 1);
527 return 0;
528 }
529 if (!(child->flags & PF_PTRACED)) {
530 DBG(DBG_MEM, ("child not traced\n"));
531 return -ESRCH;
532 }
533 if (child->state != TASK_STOPPED) {
534 DBG(DBG_MEM, ("child process not stopped\n"));
535 if (request != PTRACE_KILL)
536 return -ESRCH;
537 }
538 if (child->p_pptr != current) {
539 DBG(DBG_MEM, ("child not parent of this process\n"));
540 return -ESRCH;
541 }
542
543 switch (request) {
544
545 case PTRACE_PEEKTEXT:
546 case PTRACE_PEEKDATA: {
547 unsigned long tmp;
548 int res;
549
550 res = read_long(child, addr, &tmp);
551 DBG(DBG_MEM, ("peek %#lx->%#lx\n", addr, tmp));
552 if (res < 0)
553 return res;
554 regs.r0 = tmp;
555 return -255;
556 }
557
558
559 case PTRACE_PEEKUSR:
560 regs.r0 = get_reg(child, addr);
561 DBG(DBG_MEM, ("peek $%ld=%#lx\n", addr, regs.r0));
562 return -255;
563
564
565 case PTRACE_POKETEXT:
566 case PTRACE_POKEDATA:
567 DBG(DBG_MEM, ("poke %#lx<-%#lx\n", addr, data));
568 return write_long(child, addr, data);
569
570 case PTRACE_POKEUSR:
571 DBG(DBG_MEM, ("poke $%ld<-%#lx\n", addr, data));
572 return put_reg(child, addr, data);
573
574 case PTRACE_SYSCALL:
575
576 case PTRACE_CONT: {
577 if ((unsigned long) data > NSIG)
578 return -EIO;
579 if (request == PTRACE_SYSCALL)
580 child->flags |= PF_TRACESYS;
581 else
582 child->flags &= ~PF_TRACESYS;
583 child->exit_code = data;
584 wake_up_process(child);
585
586 ptrace_cancel_bpt(child);
587 return data;
588 }
589
590
591
592
593
594
595 case PTRACE_KILL: {
596 if (child->state != TASK_ZOMBIE) {
597 wake_up_process(child);
598 child->exit_code = SIGKILL;
599 }
600
601 ptrace_cancel_bpt(child);
602 return 0;
603 }
604
605 case PTRACE_SINGLESTEP: {
606 if ((unsigned long) data > NSIG)
607 return -EIO;
608 child->debugreg[4] = -1;
609 child->flags &= ~PF_TRACESYS;
610 wake_up_process(child);
611 child->exit_code = data;
612
613 return 0;
614 }
615
616 case PTRACE_DETACH: {
617 if ((unsigned long) data > NSIG)
618 return -EIO;
619 child->flags &= ~(PF_PTRACED|PF_TRACESYS);
620 wake_up_process(child);
621 child->exit_code = data;
622 REMOVE_LINKS(child);
623 child->p_pptr = child->p_opptr;
624 SET_LINKS(child);
625
626 ptrace_cancel_bpt(child);
627 return 0;
628 }
629
630 default:
631 return -EIO;
632 }
633 }
634
635 asmlinkage void syscall_trace(void)
636 {
637 if ((current->flags & (PF_PTRACED|PF_TRACESYS))
638 != (PF_PTRACED|PF_TRACESYS))
639 return;
640 current->exit_code = SIGTRAP;
641 current->state = TASK_STOPPED;
642 notify_parent(current);
643 schedule();
644
645
646
647
648
649 if (current->exit_code)
650 current->signal |= (1 << (current->exit_code - 1));
651 current->exit_code = 0;
652 }