diff options
Diffstat (limited to 'kernel/ptrace.c')
-rw-r--r-- | kernel/ptrace.c | 38 |
1 files changed, 26 insertions, 12 deletions
diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 42ad8ae729a0..74a3d693c196 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c | |||
@@ -14,7 +14,6 @@ | |||
14 | #include <linux/mm.h> | 14 | #include <linux/mm.h> |
15 | #include <linux/highmem.h> | 15 | #include <linux/highmem.h> |
16 | #include <linux/pagemap.h> | 16 | #include <linux/pagemap.h> |
17 | #include <linux/smp_lock.h> | ||
18 | #include <linux/ptrace.h> | 17 | #include <linux/ptrace.h> |
19 | #include <linux/security.h> | 18 | #include <linux/security.h> |
20 | #include <linux/signal.h> | 19 | #include <linux/signal.h> |
@@ -76,7 +75,6 @@ void __ptrace_unlink(struct task_struct *child) | |||
76 | child->parent = child->real_parent; | 75 | child->parent = child->real_parent; |
77 | list_del_init(&child->ptrace_entry); | 76 | list_del_init(&child->ptrace_entry); |
78 | 77 | ||
79 | arch_ptrace_untrace(child); | ||
80 | if (task_is_traced(child)) | 78 | if (task_is_traced(child)) |
81 | ptrace_untrace(child); | 79 | ptrace_untrace(child); |
82 | } | 80 | } |
@@ -596,6 +594,32 @@ int ptrace_request(struct task_struct *child, long request, | |||
596 | ret = ptrace_detach(child, data); | 594 | ret = ptrace_detach(child, data); |
597 | break; | 595 | break; |
598 | 596 | ||
597 | #ifdef CONFIG_BINFMT_ELF_FDPIC | ||
598 | case PTRACE_GETFDPIC: { | ||
599 | struct mm_struct *mm = get_task_mm(child); | ||
600 | unsigned long tmp = 0; | ||
601 | |||
602 | ret = -ESRCH; | ||
603 | if (!mm) | ||
604 | break; | ||
605 | |||
606 | switch (addr) { | ||
607 | case PTRACE_GETFDPIC_EXEC: | ||
608 | tmp = mm->context.exec_fdpic_loadmap; | ||
609 | break; | ||
610 | case PTRACE_GETFDPIC_INTERP: | ||
611 | tmp = mm->context.interp_fdpic_loadmap; | ||
612 | break; | ||
613 | default: | ||
614 | break; | ||
615 | } | ||
616 | mmput(mm); | ||
617 | |||
618 | ret = put_user(tmp, (unsigned long __user *) data); | ||
619 | break; | ||
620 | } | ||
621 | #endif | ||
622 | |||
599 | #ifdef PTRACE_SINGLESTEP | 623 | #ifdef PTRACE_SINGLESTEP |
600 | case PTRACE_SINGLESTEP: | 624 | case PTRACE_SINGLESTEP: |
601 | #endif | 625 | #endif |
@@ -666,10 +690,6 @@ SYSCALL_DEFINE4(ptrace, long, request, long, pid, long, addr, long, data) | |||
666 | struct task_struct *child; | 690 | struct task_struct *child; |
667 | long ret; | 691 | long ret; |
668 | 692 | ||
669 | /* | ||
670 | * This lock_kernel fixes a subtle race with suid exec | ||
671 | */ | ||
672 | lock_kernel(); | ||
673 | if (request == PTRACE_TRACEME) { | 693 | if (request == PTRACE_TRACEME) { |
674 | ret = ptrace_traceme(); | 694 | ret = ptrace_traceme(); |
675 | if (!ret) | 695 | if (!ret) |
@@ -703,7 +723,6 @@ SYSCALL_DEFINE4(ptrace, long, request, long, pid, long, addr, long, data) | |||
703 | out_put_task_struct: | 723 | out_put_task_struct: |
704 | put_task_struct(child); | 724 | put_task_struct(child); |
705 | out: | 725 | out: |
706 | unlock_kernel(); | ||
707 | return ret; | 726 | return ret; |
708 | } | 727 | } |
709 | 728 | ||
@@ -813,10 +832,6 @@ asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid, | |||
813 | struct task_struct *child; | 832 | struct task_struct *child; |
814 | long ret; | 833 | long ret; |
815 | 834 | ||
816 | /* | ||
817 | * This lock_kernel fixes a subtle race with suid exec | ||
818 | */ | ||
819 | lock_kernel(); | ||
820 | if (request == PTRACE_TRACEME) { | 835 | if (request == PTRACE_TRACEME) { |
821 | ret = ptrace_traceme(); | 836 | ret = ptrace_traceme(); |
822 | goto out; | 837 | goto out; |
@@ -846,7 +861,6 @@ asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid, | |||
846 | out_put_task_struct: | 861 | out_put_task_struct: |
847 | put_task_struct(child); | 862 | put_task_struct(child); |
848 | out: | 863 | out: |
849 | unlock_kernel(); | ||
850 | return ret; | 864 | return ret; |
851 | } | 865 | } |
852 | #endif /* CONFIG_COMPAT */ | 866 | #endif /* CONFIG_COMPAT */ |