aboutsummaryrefslogtreecommitdiffstats
path: root/kernel/ptrace.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/ptrace.c')
-rw-r--r--kernel/ptrace.c170
1 files changed, 117 insertions, 53 deletions
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 99bbaa3e5b0d..2df115790cd9 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -22,6 +22,7 @@
22#include <linux/syscalls.h> 22#include <linux/syscalls.h>
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 26
26 27
27/* 28/*
@@ -37,35 +38,33 @@ void __ptrace_link(struct task_struct *child, struct task_struct *new_parent)
37 child->parent = new_parent; 38 child->parent = new_parent;
38} 39}
39 40
40/* 41/**
41 * Turn a tracing stop into a normal stop now, since with no tracer there 42 * __ptrace_unlink - unlink ptracee and restore its execution state
42 * would be no way to wake it up with SIGCONT or SIGKILL. If there was a 43 * @child: ptracee to be unlinked
43 * signal sent that would resume the child, but didn't because it was in
44 * TASK_TRACED, resume it now.
45 * Requires that irqs be disabled.
46 */
47static void ptrace_untrace(struct task_struct *child)
48{
49 spin_lock(&child->sighand->siglock);
50 if (task_is_traced(child)) {
51 /*
52 * If the group stop is completed or in progress,
53 * this thread was already counted as stopped.
54 */
55 if (child->signal->flags & SIGNAL_STOP_STOPPED ||
56 child->signal->group_stop_count)
57 __set_task_state(child, TASK_STOPPED);
58 else
59 signal_wake_up(child, 1);
60 }
61 spin_unlock(&child->sighand->siglock);
62}
63
64/*
65 * unptrace a task: move it back to its original parent and
66 * remove it from the ptrace list.
67 * 44 *
68 * Must be called with the tasklist lock write-held. 45 * Remove @child from the ptrace list, move it back to the original parent,
46 * and restore the execution state so that it conforms to the group stop
47 * state.
48 *
49 * Unlinking can happen via two paths - explicit PTRACE_DETACH or ptracer
50 * exiting. For PTRACE_DETACH, unless the ptracee has been killed between
51 * ptrace_check_attach() and here, it's guaranteed to be in TASK_TRACED.
52 * If the ptracer is exiting, the ptracee can be in any state.
53 *
54 * After detach, the ptracee should be in a state which conforms to the
55 * group stop. If the group is stopped or in the process of stopping, the
56 * ptracee should be put into TASK_STOPPED; otherwise, it should be woken
57 * up from TASK_TRACED.
58 *
59 * If the ptracee is in TASK_TRACED and needs to be moved to TASK_STOPPED,
60 * it goes through TRACED -> RUNNING -> STOPPED transition which is similar
61 * to but in the opposite direction of what happens while attaching to a
62 * stopped task. However, in this direction, the intermediate RUNNING
63 * state is not hidden even from the current ptracer and if it immediately
64 * re-attaches and performs a WNOHANG wait(2), it may fail.
65 *
66 * CONTEXT:
67 * write_lock_irq(tasklist_lock)
69 */ 68 */
70void __ptrace_unlink(struct task_struct *child) 69void __ptrace_unlink(struct task_struct *child)
71{ 70{
@@ -75,8 +74,27 @@ void __ptrace_unlink(struct task_struct *child)
75 child->parent = child->real_parent; 74 child->parent = child->real_parent;
76 list_del_init(&child->ptrace_entry); 75 list_del_init(&child->ptrace_entry);
77 76
78 if (task_is_traced(child)) 77 spin_lock(&child->sighand->siglock);
79 ptrace_untrace(child); 78
79 /*
80 * Reinstate GROUP_STOP_PENDING if group stop is in effect and
81 * @child isn't dead.
82 */
83 if (!(child->flags & PF_EXITING) &&
84 (child->signal->flags & SIGNAL_STOP_STOPPED ||
85 child->signal->group_stop_count))
86 child->group_stop |= GROUP_STOP_PENDING;
87
88 /*
89 * If transition to TASK_STOPPED is pending or in TASK_TRACED, kick
90 * @child in the butt. Note that @resume should be used iff @child
91 * is in TASK_TRACED; otherwise, we might unduly disrupt
92 * TASK_KILLABLE sleeps.
93 */
94 if (child->group_stop & GROUP_STOP_PENDING || task_is_traced(child))
95 signal_wake_up(child, task_is_traced(child));
96
97 spin_unlock(&child->sighand->siglock);
80} 98}
81 99
82/* 100/*
@@ -95,16 +113,14 @@ int ptrace_check_attach(struct task_struct *child, int kill)
95 */ 113 */
96 read_lock(&tasklist_lock); 114 read_lock(&tasklist_lock);
97 if ((child->ptrace & PT_PTRACED) && child->parent == current) { 115 if ((child->ptrace & PT_PTRACED) && child->parent == current) {
98 ret = 0;
99 /* 116 /*
100 * child->sighand can't be NULL, release_task() 117 * child->sighand can't be NULL, release_task()
101 * does ptrace_unlink() before __exit_signal(). 118 * does ptrace_unlink() before __exit_signal().
102 */ 119 */
103 spin_lock_irq(&child->sighand->siglock); 120 spin_lock_irq(&child->sighand->siglock);
104 if (task_is_stopped(child)) 121 WARN_ON_ONCE(task_is_stopped(child));
105 child->state = TASK_TRACED; 122 if (task_is_traced(child) || kill)
106 else if (!task_is_traced(child) && !kill) 123 ret = 0;
107 ret = -ESRCH;
108 spin_unlock_irq(&child->sighand->siglock); 124 spin_unlock_irq(&child->sighand->siglock);
109 } 125 }
110 read_unlock(&tasklist_lock); 126 read_unlock(&tasklist_lock);
@@ -134,21 +150,24 @@ int __ptrace_may_access(struct task_struct *task, unsigned int mode)
134 return 0; 150 return 0;
135 rcu_read_lock(); 151 rcu_read_lock();
136 tcred = __task_cred(task); 152 tcred = __task_cred(task);
137 if ((cred->uid != tcred->euid || 153 if (cred->user->user_ns == tcred->user->user_ns &&
138 cred->uid != tcred->suid || 154 (cred->uid == tcred->euid &&
139 cred->uid != tcred->uid || 155 cred->uid == tcred->suid &&
140 cred->gid != tcred->egid || 156 cred->uid == tcred->uid &&
141 cred->gid != tcred->sgid || 157 cred->gid == tcred->egid &&
142 cred->gid != tcred->gid) && 158 cred->gid == tcred->sgid &&
143 !capable(CAP_SYS_PTRACE)) { 159 cred->gid == tcred->gid))
144 rcu_read_unlock(); 160 goto ok;
145 return -EPERM; 161 if (ns_capable(tcred->user->user_ns, CAP_SYS_PTRACE))
146 } 162 goto ok;
163 rcu_read_unlock();
164 return -EPERM;
165ok:
147 rcu_read_unlock(); 166 rcu_read_unlock();
148 smp_rmb(); 167 smp_rmb();
149 if (task->mm) 168 if (task->mm)
150 dumpable = get_dumpable(task->mm); 169 dumpable = get_dumpable(task->mm);
151 if (!dumpable && !capable(CAP_SYS_PTRACE)) 170 if (!dumpable && !task_ns_capable(task, CAP_SYS_PTRACE))
152 return -EPERM; 171 return -EPERM;
153 172
154 return security_ptrace_access_check(task, mode); 173 return security_ptrace_access_check(task, mode);
@@ -163,8 +182,9 @@ bool ptrace_may_access(struct task_struct *task, unsigned int mode)
163 return !err; 182 return !err;
164} 183}
165 184
166int ptrace_attach(struct task_struct *task) 185static int ptrace_attach(struct task_struct *task)
167{ 186{
187 bool wait_trap = false;
168 int retval; 188 int retval;
169 189
170 audit_ptrace(task); 190 audit_ptrace(task);
@@ -198,18 +218,48 @@ int ptrace_attach(struct task_struct *task)
198 goto unlock_tasklist; 218 goto unlock_tasklist;
199 219
200 task->ptrace = PT_PTRACED; 220 task->ptrace = PT_PTRACED;
201 if (capable(CAP_SYS_PTRACE)) 221 if (task_ns_capable(task, CAP_SYS_PTRACE))
202 task->ptrace |= PT_PTRACE_CAP; 222 task->ptrace |= PT_PTRACE_CAP;
203 223
204 __ptrace_link(task, current); 224 __ptrace_link(task, current);
205 send_sig_info(SIGSTOP, SEND_SIG_FORCED, task); 225 send_sig_info(SIGSTOP, SEND_SIG_FORCED, task);
206 226
227 spin_lock(&task->sighand->siglock);
228
229 /*
230 * If the task is already STOPPED, set GROUP_STOP_PENDING and
231 * TRAPPING, and kick it so that it transits to TRACED. TRAPPING
232 * will be cleared if the child completes the transition or any
233 * event which clears the group stop states happens. We'll wait
234 * for the transition to complete before returning from this
235 * function.
236 *
237 * This hides STOPPED -> RUNNING -> TRACED transition from the
238 * attaching thread but a different thread in the same group can
239 * still observe the transient RUNNING state. IOW, if another
240 * thread's WNOHANG wait(2) on the stopped tracee races against
241 * ATTACH, the wait(2) may fail due to the transient RUNNING.
242 *
243 * The following task_is_stopped() test is safe as both transitions
244 * in and out of STOPPED are protected by siglock.
245 */
246 if (task_is_stopped(task)) {
247 task->group_stop |= GROUP_STOP_PENDING | GROUP_STOP_TRAPPING;
248 signal_wake_up(task, 1);
249 wait_trap = true;
250 }
251
252 spin_unlock(&task->sighand->siglock);
253
207 retval = 0; 254 retval = 0;
208unlock_tasklist: 255unlock_tasklist:
209 write_unlock_irq(&tasklist_lock); 256 write_unlock_irq(&tasklist_lock);
210unlock_creds: 257unlock_creds:
211 mutex_unlock(&task->signal->cred_guard_mutex); 258 mutex_unlock(&task->signal->cred_guard_mutex);
212out: 259out:
260 if (wait_trap)
261 wait_event(current->signal->wait_chldexit,
262 !(task->group_stop & GROUP_STOP_TRAPPING));
213 return retval; 263 return retval;
214} 264}
215 265
@@ -219,7 +269,7 @@ out:
219 * Performs checks and sets PT_PTRACED. 269 * Performs checks and sets PT_PTRACED.
220 * Should be used by all ptrace implementations for PTRACE_TRACEME. 270 * Should be used by all ptrace implementations for PTRACE_TRACEME.
221 */ 271 */
222int ptrace_traceme(void) 272static int ptrace_traceme(void)
223{ 273{
224 int ret = -EPERM; 274 int ret = -EPERM;
225 275
@@ -293,7 +343,7 @@ static bool __ptrace_detach(struct task_struct *tracer, struct task_struct *p)
293 return false; 343 return false;
294} 344}
295 345
296int ptrace_detach(struct task_struct *child, unsigned int data) 346static int ptrace_detach(struct task_struct *child, unsigned int data)
297{ 347{
298 bool dead = false; 348 bool dead = false;
299 349
@@ -312,8 +362,6 @@ int ptrace_detach(struct task_struct *child, unsigned int data)
312 if (child->ptrace) { 362 if (child->ptrace) {
313 child->exit_code = data; 363 child->exit_code = data;
314 dead = __ptrace_detach(current, child); 364 dead = __ptrace_detach(current, child);
315 if (!child->exit_state)
316 wake_up_process(child);
317 } 365 }
318 write_unlock_irq(&tasklist_lock); 366 write_unlock_irq(&tasklist_lock);
319 367
@@ -514,7 +562,7 @@ static int ptrace_resume(struct task_struct *child, long request,
514 } 562 }
515 563
516 child->exit_code = data; 564 child->exit_code = data;
517 wake_up_process(child); 565 wake_up_state(child, __TASK_TRACED);
518 566
519 return 0; 567 return 0;
520} 568}
@@ -876,3 +924,19 @@ asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid,
876 return ret; 924 return ret;
877} 925}
878#endif /* CONFIG_COMPAT */ 926#endif /* CONFIG_COMPAT */
927
928#ifdef CONFIG_HAVE_HW_BREAKPOINT
929int ptrace_get_breakpoints(struct task_struct *tsk)
930{
931 if (atomic_inc_not_zero(&tsk->ptrace_bp_refcnt))
932 return 0;
933
934 return -1;
935}
936
937void ptrace_put_breakpoints(struct task_struct *tsk)
938{
939 if (atomic_dec_and_test(&tsk->ptrace_bp_refcnt))
940 flush_ptrace_hw_breakpoint(tsk);
941}
942#endif /* CONFIG_HAVE_HW_BREAKPOINT */