diff options
author | Christoph Hellwig <hch@lst.de> | 2005-11-07 03:59:47 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@g5.osdl.org> | 2005-11-07 10:53:42 -0500 |
commit | 481bed454247538e9f57d4ea37b153ccba24ba7b (patch) | |
tree | bb4198296962c08dbf52e8f377dc27206f621640 /kernel | |
parent | db73e9aa99bf093427b79877f9475392724fd5e5 (diff) |
[PATCH] consolidate sys_ptrace()
The sys_ptrace boilerplate code (everything outside the big switch
statement for the arch-specific requests) is shared by most architectures.
This patch moves it to kernel/ptrace.c and leaves the arch-specific code as
arch_ptrace.
Some architectures have a too different ptrace so we have to exclude them.
They continue to keep their implementations. For sh64 I had to add a
sh64_ptrace wrapper because it does some initialization on the first call.
For um I removed an ifdefed SUBARCH_PTRACE_SPECIAL block, but
SUBARCH_PTRACE_SPECIAL isn't defined anywhere in the tree.
Signed-off-by: Christoph Hellwig <hch@lst.de>
Acked-by: Paul Mackerras <paulus@samba.org>
Acked-by: Ralf Baechle <ralf@linux-mips.org>
Acked-By: David Howells <dhowells@redhat.com>
Acked-by: Russell King <rmk+kernel@arm.linux.org.uk>
Acked-by: Paul Mundt <lethal@linux-sh.org>
Signed-off-by: Andrew Morton <akpm@osdl.org>
Signed-off-by: Linus Torvalds <torvalds@osdl.org>
Diffstat (limited to 'kernel')
-rw-r--r-- | kernel/ptrace.c | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 863eee8bff47..5b8dd98a230e 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c | |||
@@ -406,3 +406,85 @@ int ptrace_request(struct task_struct *child, long request, | |||
406 | 406 | ||
407 | return ret; | 407 | return ret; |
408 | } | 408 | } |
409 | |||
410 | #ifndef __ARCH_SYS_PTRACE | ||
411 | static int ptrace_get_task_struct(long request, long pid, | ||
412 | struct task_struct **childp) | ||
413 | { | ||
414 | struct task_struct *child; | ||
415 | int ret; | ||
416 | |||
417 | /* | ||
418 | * Callers use child == NULL as an indication to exit early even | ||
419 | * when the return value is 0, so make sure it is non-NULL here. | ||
420 | */ | ||
421 | *childp = NULL; | ||
422 | |||
423 | if (request == PTRACE_TRACEME) { | ||
424 | /* | ||
425 | * Are we already being traced? | ||
426 | */ | ||
427 | if (current->ptrace & PT_PTRACED) | ||
428 | return -EPERM; | ||
429 | ret = security_ptrace(current->parent, current); | ||
430 | if (ret) | ||
431 | return -EPERM; | ||
432 | /* | ||
433 | * Set the ptrace bit in the process ptrace flags. | ||
434 | */ | ||
435 | current->ptrace |= PT_PTRACED; | ||
436 | return 0; | ||
437 | } | ||
438 | |||
439 | /* | ||
440 | * You may not mess with init | ||
441 | */ | ||
442 | if (pid == 1) | ||
443 | return -EPERM; | ||
444 | |||
445 | ret = -ESRCH; | ||
446 | read_lock(&tasklist_lock); | ||
447 | child = find_task_by_pid(pid); | ||
448 | if (child) | ||
449 | get_task_struct(child); | ||
450 | read_unlock(&tasklist_lock); | ||
451 | if (!child) | ||
452 | return -ESRCH; | ||
453 | |||
454 | *childp = child; | ||
455 | return 0; | ||
456 | } | ||
457 | |||
458 | asmlinkage long sys_ptrace(long request, long pid, long addr, long data) | ||
459 | { | ||
460 | struct task_struct *child; | ||
461 | long ret; | ||
462 | |||
463 | /* | ||
464 | * This lock_kernel fixes a subtle race with suid exec | ||
465 | */ | ||
466 | lock_kernel(); | ||
467 | ret = ptrace_get_task_struct(request, pid, &child); | ||
468 | if (!child) | ||
469 | goto out; | ||
470 | |||
471 | if (request == PTRACE_ATTACH) { | ||
472 | ret = ptrace_attach(child); | ||
473 | goto out; | ||
474 | } | ||
475 | |||
476 | ret = ptrace_check_attach(child, request == PTRACE_KILL); | ||
477 | if (ret < 0) | ||
478 | goto out_put_task_struct; | ||
479 | |||
480 | ret = arch_ptrace(child, request, addr, data); | ||
481 | if (ret < 0) | ||
482 | goto out_put_task_struct; | ||
483 | |||
484 | out_put_task_struct: | ||
485 | put_task_struct(child); | ||
486 | out: | ||
487 | unlock_kernel(); | ||
488 | return ret; | ||
489 | } | ||
490 | #endif /* __ARCH_SYS_PTRACE */ | ||