diff options
Diffstat (limited to 'kernel/ptrace.c')
-rw-r--r-- | kernel/ptrace.c | 197 |
1 files changed, 156 insertions, 41 deletions
diff --git a/kernel/ptrace.c b/kernel/ptrace.c index 2df115790cd9..9de3ecfd20f9 100644 --- a/kernel/ptrace.c +++ b/kernel/ptrace.c | |||
@@ -23,8 +23,15 @@ | |||
23 | #include <linux/uaccess.h> | 23 | #include <linux/uaccess.h> |
24 | #include <linux/regset.h> | 24 | #include <linux/regset.h> |
25 | #include <linux/hw_breakpoint.h> | 25 | #include <linux/hw_breakpoint.h> |
26 | #include <linux/cn_proc.h> | ||
26 | 27 | ||
27 | 28 | ||
29 | static int ptrace_trapping_sleep_fn(void *flags) | ||
30 | { | ||
31 | schedule(); | ||
32 | return 0; | ||
33 | } | ||
34 | |||
28 | /* | 35 | /* |
29 | * ptrace a task: make the debugger its new parent and | 36 | * ptrace a task: make the debugger its new parent and |
30 | * move it to the ptrace list. | 37 | * move it to the ptrace list. |
@@ -77,13 +84,20 @@ void __ptrace_unlink(struct task_struct *child) | |||
77 | spin_lock(&child->sighand->siglock); | 84 | spin_lock(&child->sighand->siglock); |
78 | 85 | ||
79 | /* | 86 | /* |
80 | * Reinstate GROUP_STOP_PENDING if group stop is in effect and | 87 | * Clear all pending traps and TRAPPING. TRAPPING should be |
88 | * cleared regardless of JOBCTL_STOP_PENDING. Do it explicitly. | ||
89 | */ | ||
90 | task_clear_jobctl_pending(child, JOBCTL_TRAP_MASK); | ||
91 | task_clear_jobctl_trapping(child); | ||
92 | |||
93 | /* | ||
94 | * Reinstate JOBCTL_STOP_PENDING if group stop is in effect and | ||
81 | * @child isn't dead. | 95 | * @child isn't dead. |
82 | */ | 96 | */ |
83 | if (!(child->flags & PF_EXITING) && | 97 | if (!(child->flags & PF_EXITING) && |
84 | (child->signal->flags & SIGNAL_STOP_STOPPED || | 98 | (child->signal->flags & SIGNAL_STOP_STOPPED || |
85 | child->signal->group_stop_count)) | 99 | child->signal->group_stop_count)) |
86 | child->group_stop |= GROUP_STOP_PENDING; | 100 | child->jobctl |= JOBCTL_STOP_PENDING; |
87 | 101 | ||
88 | /* | 102 | /* |
89 | * If transition to TASK_STOPPED is pending or in TASK_TRACED, kick | 103 | * If transition to TASK_STOPPED is pending or in TASK_TRACED, kick |
@@ -91,16 +105,30 @@ void __ptrace_unlink(struct task_struct *child) | |||
91 | * is in TASK_TRACED; otherwise, we might unduly disrupt | 105 | * is in TASK_TRACED; otherwise, we might unduly disrupt |
92 | * TASK_KILLABLE sleeps. | 106 | * TASK_KILLABLE sleeps. |
93 | */ | 107 | */ |
94 | if (child->group_stop & GROUP_STOP_PENDING || task_is_traced(child)) | 108 | if (child->jobctl & JOBCTL_STOP_PENDING || task_is_traced(child)) |
95 | signal_wake_up(child, task_is_traced(child)); | 109 | signal_wake_up(child, task_is_traced(child)); |
96 | 110 | ||
97 | spin_unlock(&child->sighand->siglock); | 111 | spin_unlock(&child->sighand->siglock); |
98 | } | 112 | } |
99 | 113 | ||
100 | /* | 114 | /** |
101 | * Check that we have indeed attached to the thing.. | 115 | * ptrace_check_attach - check whether ptracee is ready for ptrace operation |
116 | * @child: ptracee to check for | ||
117 | * @ignore_state: don't check whether @child is currently %TASK_TRACED | ||
118 | * | ||
119 | * Check whether @child is being ptraced by %current and ready for further | ||
120 | * ptrace operations. If @ignore_state is %false, @child also should be in | ||
121 | * %TASK_TRACED state and on return the child is guaranteed to be traced | ||
122 | * and not executing. If @ignore_state is %true, @child can be in any | ||
123 | * state. | ||
124 | * | ||
125 | * CONTEXT: | ||
126 | * Grabs and releases tasklist_lock and @child->sighand->siglock. | ||
127 | * | ||
128 | * RETURNS: | ||
129 | * 0 on success, -ESRCH if %child is not ready. | ||
102 | */ | 130 | */ |
103 | int ptrace_check_attach(struct task_struct *child, int kill) | 131 | int ptrace_check_attach(struct task_struct *child, bool ignore_state) |
104 | { | 132 | { |
105 | int ret = -ESRCH; | 133 | int ret = -ESRCH; |
106 | 134 | ||
@@ -119,13 +147,14 @@ int ptrace_check_attach(struct task_struct *child, int kill) | |||
119 | */ | 147 | */ |
120 | spin_lock_irq(&child->sighand->siglock); | 148 | spin_lock_irq(&child->sighand->siglock); |
121 | WARN_ON_ONCE(task_is_stopped(child)); | 149 | WARN_ON_ONCE(task_is_stopped(child)); |
122 | if (task_is_traced(child) || kill) | 150 | if (ignore_state || (task_is_traced(child) && |
151 | !(child->jobctl & JOBCTL_LISTENING))) | ||
123 | ret = 0; | 152 | ret = 0; |
124 | spin_unlock_irq(&child->sighand->siglock); | 153 | spin_unlock_irq(&child->sighand->siglock); |
125 | } | 154 | } |
126 | read_unlock(&tasklist_lock); | 155 | read_unlock(&tasklist_lock); |
127 | 156 | ||
128 | if (!ret && !kill) | 157 | if (!ret && !ignore_state) |
129 | ret = wait_task_inactive(child, TASK_TRACED) ? 0 : -ESRCH; | 158 | ret = wait_task_inactive(child, TASK_TRACED) ? 0 : -ESRCH; |
130 | 159 | ||
131 | /* All systems go.. */ | 160 | /* All systems go.. */ |
@@ -182,11 +211,28 @@ bool ptrace_may_access(struct task_struct *task, unsigned int mode) | |||
182 | return !err; | 211 | return !err; |
183 | } | 212 | } |
184 | 213 | ||
185 | static int ptrace_attach(struct task_struct *task) | 214 | static int ptrace_attach(struct task_struct *task, long request, |
215 | unsigned long flags) | ||
186 | { | 216 | { |
187 | bool wait_trap = false; | 217 | bool seize = (request == PTRACE_SEIZE); |
188 | int retval; | 218 | int retval; |
189 | 219 | ||
220 | /* | ||
221 | * SEIZE will enable new ptrace behaviors which will be implemented | ||
222 | * gradually. SEIZE_DEVEL is used to prevent applications | ||
223 | * expecting full SEIZE behaviors trapping on kernel commits which | ||
224 | * are still in the process of implementing them. | ||
225 | * | ||
226 | * Only test programs for new ptrace behaviors being implemented | ||
227 | * should set SEIZE_DEVEL. If unset, SEIZE will fail with -EIO. | ||
228 | * | ||
229 | * Once SEIZE behaviors are completely implemented, this flag and | ||
230 | * the following test will be removed. | ||
231 | */ | ||
232 | retval = -EIO; | ||
233 | if (seize && !(flags & PTRACE_SEIZE_DEVEL)) | ||
234 | goto out; | ||
235 | |||
190 | audit_ptrace(task); | 236 | audit_ptrace(task); |
191 | 237 | ||
192 | retval = -EPERM; | 238 | retval = -EPERM; |
@@ -218,16 +264,21 @@ static int ptrace_attach(struct task_struct *task) | |||
218 | goto unlock_tasklist; | 264 | goto unlock_tasklist; |
219 | 265 | ||
220 | task->ptrace = PT_PTRACED; | 266 | task->ptrace = PT_PTRACED; |
267 | if (seize) | ||
268 | task->ptrace |= PT_SEIZED; | ||
221 | if (task_ns_capable(task, CAP_SYS_PTRACE)) | 269 | if (task_ns_capable(task, CAP_SYS_PTRACE)) |
222 | task->ptrace |= PT_PTRACE_CAP; | 270 | task->ptrace |= PT_PTRACE_CAP; |
223 | 271 | ||
224 | __ptrace_link(task, current); | 272 | __ptrace_link(task, current); |
225 | send_sig_info(SIGSTOP, SEND_SIG_FORCED, task); | 273 | |
274 | /* SEIZE doesn't trap tracee on attach */ | ||
275 | if (!seize) | ||
276 | send_sig_info(SIGSTOP, SEND_SIG_FORCED, task); | ||
226 | 277 | ||
227 | spin_lock(&task->sighand->siglock); | 278 | spin_lock(&task->sighand->siglock); |
228 | 279 | ||
229 | /* | 280 | /* |
230 | * If the task is already STOPPED, set GROUP_STOP_PENDING and | 281 | * If the task is already STOPPED, set JOBCTL_TRAP_STOP and |
231 | * TRAPPING, and kick it so that it transits to TRACED. TRAPPING | 282 | * TRAPPING, and kick it so that it transits to TRACED. TRAPPING |
232 | * will be cleared if the child completes the transition or any | 283 | * will be cleared if the child completes the transition or any |
233 | * event which clears the group stop states happens. We'll wait | 284 | * event which clears the group stop states happens. We'll wait |
@@ -243,11 +294,9 @@ static int ptrace_attach(struct task_struct *task) | |||
243 | * The following task_is_stopped() test is safe as both transitions | 294 | * The following task_is_stopped() test is safe as both transitions |
244 | * in and out of STOPPED are protected by siglock. | 295 | * in and out of STOPPED are protected by siglock. |
245 | */ | 296 | */ |
246 | if (task_is_stopped(task)) { | 297 | if (task_is_stopped(task) && |
247 | task->group_stop |= GROUP_STOP_PENDING | GROUP_STOP_TRAPPING; | 298 | task_set_jobctl_pending(task, JOBCTL_TRAP_STOP | JOBCTL_TRAPPING)) |
248 | signal_wake_up(task, 1); | 299 | signal_wake_up(task, 1); |
249 | wait_trap = true; | ||
250 | } | ||
251 | 300 | ||
252 | spin_unlock(&task->sighand->siglock); | 301 | spin_unlock(&task->sighand->siglock); |
253 | 302 | ||
@@ -257,9 +306,12 @@ unlock_tasklist: | |||
257 | unlock_creds: | 306 | unlock_creds: |
258 | mutex_unlock(&task->signal->cred_guard_mutex); | 307 | mutex_unlock(&task->signal->cred_guard_mutex); |
259 | out: | 308 | out: |
260 | if (wait_trap) | 309 | if (!retval) { |
261 | wait_event(current->signal->wait_chldexit, | 310 | wait_on_bit(&task->jobctl, JOBCTL_TRAPPING_BIT, |
262 | !(task->group_stop & GROUP_STOP_TRAPPING)); | 311 | ptrace_trapping_sleep_fn, TASK_UNINTERRUPTIBLE); |
312 | proc_ptrace_connector(task, PTRACE_ATTACH); | ||
313 | } | ||
314 | |||
263 | return retval; | 315 | return retval; |
264 | } | 316 | } |
265 | 317 | ||
@@ -322,25 +374,27 @@ static int ignoring_children(struct sighand_struct *sigh) | |||
322 | */ | 374 | */ |
323 | static bool __ptrace_detach(struct task_struct *tracer, struct task_struct *p) | 375 | static bool __ptrace_detach(struct task_struct *tracer, struct task_struct *p) |
324 | { | 376 | { |
377 | bool dead; | ||
378 | |||
325 | __ptrace_unlink(p); | 379 | __ptrace_unlink(p); |
326 | 380 | ||
327 | if (p->exit_state == EXIT_ZOMBIE) { | 381 | if (p->exit_state != EXIT_ZOMBIE) |
328 | if (!task_detached(p) && thread_group_empty(p)) { | 382 | return false; |
329 | if (!same_thread_group(p->real_parent, tracer)) | 383 | |
330 | do_notify_parent(p, p->exit_signal); | 384 | dead = !thread_group_leader(p); |
331 | else if (ignoring_children(tracer->sighand)) { | 385 | |
332 | __wake_up_parent(p, tracer); | 386 | if (!dead && thread_group_empty(p)) { |
333 | p->exit_signal = -1; | 387 | if (!same_thread_group(p->real_parent, tracer)) |
334 | } | 388 | dead = do_notify_parent(p, p->exit_signal); |
335 | } | 389 | else if (ignoring_children(tracer->sighand)) { |
336 | if (task_detached(p)) { | 390 | __wake_up_parent(p, tracer); |
337 | /* Mark it as in the process of being reaped. */ | 391 | dead = true; |
338 | p->exit_state = EXIT_DEAD; | ||
339 | return true; | ||
340 | } | 392 | } |
341 | } | 393 | } |
342 | 394 | /* Mark it as in the process of being reaped. */ | |
343 | return false; | 395 | if (dead) |
396 | p->exit_state = EXIT_DEAD; | ||
397 | return dead; | ||
344 | } | 398 | } |
345 | 399 | ||
346 | static int ptrace_detach(struct task_struct *child, unsigned int data) | 400 | static int ptrace_detach(struct task_struct *child, unsigned int data) |
@@ -365,6 +419,7 @@ static int ptrace_detach(struct task_struct *child, unsigned int data) | |||
365 | } | 419 | } |
366 | write_unlock_irq(&tasklist_lock); | 420 | write_unlock_irq(&tasklist_lock); |
367 | 421 | ||
422 | proc_ptrace_connector(child, PTRACE_DETACH); | ||
368 | if (unlikely(dead)) | 423 | if (unlikely(dead)) |
369 | release_task(child); | 424 | release_task(child); |
370 | 425 | ||
@@ -611,10 +666,12 @@ static int ptrace_regset(struct task_struct *task, int req, unsigned int type, | |||
611 | int ptrace_request(struct task_struct *child, long request, | 666 | int ptrace_request(struct task_struct *child, long request, |
612 | unsigned long addr, unsigned long data) | 667 | unsigned long addr, unsigned long data) |
613 | { | 668 | { |
669 | bool seized = child->ptrace & PT_SEIZED; | ||
614 | int ret = -EIO; | 670 | int ret = -EIO; |
615 | siginfo_t siginfo; | 671 | siginfo_t siginfo, *si; |
616 | void __user *datavp = (void __user *) data; | 672 | void __user *datavp = (void __user *) data; |
617 | unsigned long __user *datalp = datavp; | 673 | unsigned long __user *datalp = datavp; |
674 | unsigned long flags; | ||
618 | 675 | ||
619 | switch (request) { | 676 | switch (request) { |
620 | case PTRACE_PEEKTEXT: | 677 | case PTRACE_PEEKTEXT: |
@@ -647,6 +704,62 @@ int ptrace_request(struct task_struct *child, long request, | |||
647 | ret = ptrace_setsiginfo(child, &siginfo); | 704 | ret = ptrace_setsiginfo(child, &siginfo); |
648 | break; | 705 | break; |
649 | 706 | ||
707 | case PTRACE_INTERRUPT: | ||
708 | /* | ||
709 | * Stop tracee without any side-effect on signal or job | ||
710 | * control. At least one trap is guaranteed to happen | ||
711 | * after this request. If @child is already trapped, the | ||
712 | * current trap is not disturbed and another trap will | ||
713 | * happen after the current trap is ended with PTRACE_CONT. | ||
714 | * | ||
715 | * The actual trap might not be PTRACE_EVENT_STOP trap but | ||
716 | * the pending condition is cleared regardless. | ||
717 | */ | ||
718 | if (unlikely(!seized || !lock_task_sighand(child, &flags))) | ||
719 | break; | ||
720 | |||
721 | /* | ||
722 | * INTERRUPT doesn't disturb existing trap sans one | ||
723 | * exception. If ptracer issued LISTEN for the current | ||
724 | * STOP, this INTERRUPT should clear LISTEN and re-trap | ||
725 | * tracee into STOP. | ||
726 | */ | ||
727 | if (likely(task_set_jobctl_pending(child, JOBCTL_TRAP_STOP))) | ||
728 | signal_wake_up(child, child->jobctl & JOBCTL_LISTENING); | ||
729 | |||
730 | unlock_task_sighand(child, &flags); | ||
731 | ret = 0; | ||
732 | break; | ||
733 | |||
734 | case PTRACE_LISTEN: | ||
735 | /* | ||
736 | * Listen for events. Tracee must be in STOP. It's not | ||
737 | * resumed per-se but is not considered to be in TRACED by | ||
738 | * wait(2) or ptrace(2). If an async event (e.g. group | ||
739 | * stop state change) happens, tracee will enter STOP trap | ||
740 | * again. Alternatively, ptracer can issue INTERRUPT to | ||
741 | * finish listening and re-trap tracee into STOP. | ||
742 | */ | ||
743 | if (unlikely(!seized || !lock_task_sighand(child, &flags))) | ||
744 | break; | ||
745 | |||
746 | si = child->last_siginfo; | ||
747 | if (unlikely(!si || si->si_code >> 8 != PTRACE_EVENT_STOP)) | ||
748 | break; | ||
749 | |||
750 | child->jobctl |= JOBCTL_LISTENING; | ||
751 | |||
752 | /* | ||
753 | * If NOTIFY is set, it means event happened between start | ||
754 | * of this trap and now. Trigger re-trap immediately. | ||
755 | */ | ||
756 | if (child->jobctl & JOBCTL_TRAP_NOTIFY) | ||
757 | signal_wake_up(child, true); | ||
758 | |||
759 | unlock_task_sighand(child, &flags); | ||
760 | ret = 0; | ||
761 | break; | ||
762 | |||
650 | case PTRACE_DETACH: /* detach a process that was attached. */ | 763 | case PTRACE_DETACH: /* detach a process that was attached. */ |
651 | ret = ptrace_detach(child, data); | 764 | ret = ptrace_detach(child, data); |
652 | break; | 765 | break; |
@@ -761,8 +874,8 @@ SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr, | |||
761 | goto out; | 874 | goto out; |
762 | } | 875 | } |
763 | 876 | ||
764 | if (request == PTRACE_ATTACH) { | 877 | if (request == PTRACE_ATTACH || request == PTRACE_SEIZE) { |
765 | ret = ptrace_attach(child); | 878 | ret = ptrace_attach(child, request, data); |
766 | /* | 879 | /* |
767 | * Some architectures need to do book-keeping after | 880 | * Some architectures need to do book-keeping after |
768 | * a ptrace attach. | 881 | * a ptrace attach. |
@@ -772,7 +885,8 @@ SYSCALL_DEFINE4(ptrace, long, request, long, pid, unsigned long, addr, | |||
772 | goto out_put_task_struct; | 885 | goto out_put_task_struct; |
773 | } | 886 | } |
774 | 887 | ||
775 | ret = ptrace_check_attach(child, request == PTRACE_KILL); | 888 | ret = ptrace_check_attach(child, request == PTRACE_KILL || |
889 | request == PTRACE_INTERRUPT); | ||
776 | if (ret < 0) | 890 | if (ret < 0) |
777 | goto out_put_task_struct; | 891 | goto out_put_task_struct; |
778 | 892 | ||
@@ -903,8 +1017,8 @@ asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid, | |||
903 | goto out; | 1017 | goto out; |
904 | } | 1018 | } |
905 | 1019 | ||
906 | if (request == PTRACE_ATTACH) { | 1020 | if (request == PTRACE_ATTACH || request == PTRACE_SEIZE) { |
907 | ret = ptrace_attach(child); | 1021 | ret = ptrace_attach(child, request, data); |
908 | /* | 1022 | /* |
909 | * Some architectures need to do book-keeping after | 1023 | * Some architectures need to do book-keeping after |
910 | * a ptrace attach. | 1024 | * a ptrace attach. |
@@ -914,7 +1028,8 @@ asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid, | |||
914 | goto out_put_task_struct; | 1028 | goto out_put_task_struct; |
915 | } | 1029 | } |
916 | 1030 | ||
917 | ret = ptrace_check_attach(child, request == PTRACE_KILL); | 1031 | ret = ptrace_check_attach(child, request == PTRACE_KILL || |
1032 | request == PTRACE_INTERRUPT); | ||
918 | if (!ret) | 1033 | if (!ret) |
919 | ret = compat_arch_ptrace(child, request, addr, data); | 1034 | ret = compat_arch_ptrace(child, request, addr, data); |
920 | 1035 | ||