aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/ptrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/ptrace.c')
-rw-r--r--kernel/ptrace.c38
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 */