This commit was manufactured by cvs2svn to create branch 'vserver'.
[linux-2.6.git] / kernel / ptrace.c
1 /*
2  * linux/kernel/ptrace.c
3  *
4  * (C) Copyright 1999 Linus Torvalds
5  *
6  * Common interfaces for "ptrace()" which we do not want
7  * to continually duplicate across every architecture.
8  */
9
10 #include <linux/capability.h>
11 #include <linux/module.h>
12 #include <linux/sched.h>
13 #include <linux/errno.h>
14 #include <linux/mm.h>
15 #include <linux/highmem.h>
16 #include <linux/pagemap.h>
17 #include <linux/smp_lock.h>
18 #include <linux/ptrace.h>
19 #include <linux/security.h>
20 #include <linux/signal.h>
21 #include <linux/vs_cvirt.h>
22
23 #include <asm/pgtable.h>
24 #include <asm/uaccess.h>
25
26 /*
27  * ptrace a task: make the debugger its new parent and
28  * move it to the ptrace list.
29  *
30  * Must be called with the tasklist lock write-held.
31  */
32 void __ptrace_link(task_t *child, task_t *new_parent)
33 {
34         if (!list_empty(&child->ptrace_list))
35                 BUG();
36         if (child->parent == new_parent)
37                 return;
38         list_add(&child->ptrace_list, &child->parent->ptrace_children);
39         REMOVE_LINKS(child);
40         child->parent = new_parent;
41         SET_LINKS(child);
42 }
43  
44 /*
45  * Turn a tracing stop into a normal stop now, since with no tracer there
46  * would be no way to wake it up with SIGCONT or SIGKILL.  If there was a
47  * signal sent that would resume the child, but didn't because it was in
48  * TASK_TRACED, resume it now.
49  * Requires that irqs be disabled.
50  */
51 void ptrace_untrace(task_t *child)
52 {
53         spin_lock(&child->sighand->siglock);
54         if (child->state == TASK_TRACED) {
55                 if (child->signal->flags & SIGNAL_STOP_STOPPED) {
56                         child->state = TASK_STOPPED;
57                 } else {
58                         signal_wake_up(child, 1);
59                 }
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  *
68  * Must be called with the tasklist lock write-held.
69  */
70 void __ptrace_unlink(task_t *child)
71 {
72         BUG_ON(!child->ptrace);
73
74         child->ptrace = 0;
75         if (!list_empty(&child->ptrace_list)) {
76                 list_del_init(&child->ptrace_list);
77                 REMOVE_LINKS(child);
78                 child->parent = child->real_parent;
79                 SET_LINKS(child);
80         }
81
82         if (child->state == TASK_TRACED)
83                 ptrace_untrace(child);
84 }
85
86 /*
87  * Check that we have indeed attached to the thing..
88  */
89 int ptrace_check_attach(struct task_struct *child, int kill)
90 {
91         int ret = -ESRCH;
92
93         /*
94          * We take the read lock around doing both checks to close a
95          * possible race where someone else was tracing our child and
96          * detached between these two checks.  After this locked check,
97          * we are sure that this is our traced child and that can only
98          * be changed by us so it's not changing right after this.
99          */
100         read_lock(&tasklist_lock);
101         if ((child->ptrace & PT_PTRACED) && child->parent == current &&
102             (!(child->ptrace & PT_ATTACHED) || child->real_parent != current)
103             && child->signal != NULL) {
104                 ret = 0;
105                 spin_lock_irq(&child->sighand->siglock);
106                 if (child->state == TASK_STOPPED) {
107                         child->state = TASK_TRACED;
108                 } else if (child->state != TASK_TRACED && !kill) {
109                         ret = -ESRCH;
110                 }
111                 spin_unlock_irq(&child->sighand->siglock);
112         }
113         read_unlock(&tasklist_lock);
114
115         if (!ret && !kill) {
116                 wait_task_inactive(child);
117         }
118
119         /* All systems go.. */
120         return ret;
121 }
122
123 static int may_attach(struct task_struct *task)
124 {
125         if (!task->mm)
126                 return -EPERM;
127         if (((current->uid != task->euid) ||
128              (current->uid != task->suid) ||
129              (current->uid != task->uid) ||
130              (current->gid != task->egid) ||
131              (current->gid != task->sgid) ||
132              (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
133                 return -EPERM;
134         smp_rmb();
135         if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE))
136                 return -EPERM;
137
138         return security_ptrace(current, task);
139 }
140
141 int ptrace_may_attach(struct task_struct *task)
142 {
143         int err;
144         task_lock(task);
145         err = may_attach(task);
146         task_unlock(task);
147         return !err;
148 }
149
150 int ptrace_attach(struct task_struct *task)
151 {
152         int retval;
153
154         retval = -EPERM;
155         if (task->pid <= 1)
156                 goto out;
157         if (task->tgid == current->tgid)
158                 goto out;
159
160 repeat:
161         /*
162          * Nasty, nasty.
163          *
164          * We want to hold both the task-lock and the
165          * tasklist_lock for writing at the same time.
166          * But that's against the rules (tasklist_lock
167          * is taken for reading by interrupts on other
168          * cpu's that may have task_lock).
169          */
170         task_lock(task);
171         local_irq_disable();
172         if (!write_trylock(&tasklist_lock)) {
173                 local_irq_enable();
174                 task_unlock(task);
175                 do {
176                         cpu_relax();
177                 } while (!write_can_lock(&tasklist_lock));
178                 goto repeat;
179         }
180
181         /* the same process cannot be attached many times */
182         if (task->ptrace & PT_PTRACED)
183                 goto bad;
184         retval = may_attach(task);
185         if (retval)
186                 goto bad;
187
188         /* Go */
189         task->ptrace |= PT_PTRACED | ((task->real_parent != current)
190                                       ? PT_ATTACHED : 0);
191         if (capable(CAP_SYS_PTRACE))
192                 task->ptrace |= PT_PTRACE_CAP;
193
194         __ptrace_link(task, current);
195
196         force_sig_specific(SIGSTOP, task);
197
198 bad:
199         write_unlock_irq(&tasklist_lock);
200         task_unlock(task);
201 out:
202         return retval;
203 }
204
205 void __ptrace_detach(struct task_struct *child, unsigned int data)
206 {
207         child->exit_code = data;
208         /* .. re-parent .. */
209         __ptrace_unlink(child);
210         /* .. and wake it up. */
211         if (child->exit_state != EXIT_ZOMBIE)
212                 wake_up_process(child);
213 }
214
215 int ptrace_detach(struct task_struct *child, unsigned int data)
216 {
217         if (!valid_signal(data))
218                 return -EIO;
219
220         /* Architecture-specific hardware disable .. */
221         ptrace_disable(child);
222
223         write_lock_irq(&tasklist_lock);
224         if (child->ptrace)
225                 __ptrace_detach(child, data);
226         write_unlock_irq(&tasklist_lock);
227
228         return 0;
229 }
230
231 /*
232  * Access another process' address space.
233  * Source/target buffer must be kernel space, 
234  * Do not walk the page table directly, use get_user_pages
235  */
236
237 int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write)
238 {
239         struct mm_struct *mm;
240         struct vm_area_struct *vma;
241         struct page *page;
242         void *old_buf = buf;
243
244         mm = get_task_mm(tsk);
245         if (!mm)
246                 return 0;
247
248         down_read(&mm->mmap_sem);
249         /* ignore errors, just check how much was sucessfully transfered */
250         while (len) {
251                 int bytes, ret, offset;
252                 void *maddr;
253
254                 ret = get_user_pages(tsk, mm, addr, 1,
255                                 write, 1, &page, &vma);
256                 if (ret <= 0)
257                         break;
258
259                 bytes = len;
260                 offset = addr & (PAGE_SIZE-1);
261                 if (bytes > PAGE_SIZE-offset)
262                         bytes = PAGE_SIZE-offset;
263
264                 maddr = kmap(page);
265                 if (write) {
266                         copy_to_user_page(vma, page, addr,
267                                           maddr + offset, buf, bytes);
268                         set_page_dirty_lock(page);
269                 } else {
270                         copy_from_user_page(vma, page, addr,
271                                             buf, maddr + offset, bytes);
272                 }
273                 kunmap(page);
274                 page_cache_release(page);
275                 len -= bytes;
276                 buf += bytes;
277                 addr += bytes;
278         }
279         up_read(&mm->mmap_sem);
280         mmput(mm);
281         
282         return buf - old_buf;
283 }
284
285 int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len)
286 {
287         int copied = 0;
288
289         while (len > 0) {
290                 char buf[128];
291                 int this_len, retval;
292
293                 this_len = (len > sizeof(buf)) ? sizeof(buf) : len;
294                 retval = access_process_vm(tsk, src, buf, this_len, 0);
295                 if (!retval) {
296                         if (copied)
297                                 break;
298                         return -EIO;
299                 }
300                 if (copy_to_user(dst, buf, retval))
301                         return -EFAULT;
302                 copied += retval;
303                 src += retval;
304                 dst += retval;
305                 len -= retval;                  
306         }
307         return copied;
308 }
309
310 int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int len)
311 {
312         int copied = 0;
313
314         while (len > 0) {
315                 char buf[128];
316                 int this_len, retval;
317
318                 this_len = (len > sizeof(buf)) ? sizeof(buf) : len;
319                 if (copy_from_user(buf, src, this_len))
320                         return -EFAULT;
321                 retval = access_process_vm(tsk, dst, buf, this_len, 1);
322                 if (!retval) {
323                         if (copied)
324                                 break;
325                         return -EIO;
326                 }
327                 copied += retval;
328                 src += retval;
329                 dst += retval;
330                 len -= retval;                  
331         }
332         return copied;
333 }
334
335 static int ptrace_setoptions(struct task_struct *child, long data)
336 {
337         child->ptrace &= ~PT_TRACE_MASK;
338
339         if (data & PTRACE_O_TRACESYSGOOD)
340                 child->ptrace |= PT_TRACESYSGOOD;
341
342         if (data & PTRACE_O_TRACEFORK)
343                 child->ptrace |= PT_TRACE_FORK;
344
345         if (data & PTRACE_O_TRACEVFORK)
346                 child->ptrace |= PT_TRACE_VFORK;
347
348         if (data & PTRACE_O_TRACECLONE)
349                 child->ptrace |= PT_TRACE_CLONE;
350
351         if (data & PTRACE_O_TRACEEXEC)
352                 child->ptrace |= PT_TRACE_EXEC;
353
354         if (data & PTRACE_O_TRACEVFORKDONE)
355                 child->ptrace |= PT_TRACE_VFORK_DONE;
356
357         if (data & PTRACE_O_TRACEEXIT)
358                 child->ptrace |= PT_TRACE_EXIT;
359
360         return (data & ~PTRACE_O_MASK) ? -EINVAL : 0;
361 }
362
363 static int ptrace_getsiginfo(struct task_struct *child, siginfo_t __user * data)
364 {
365         siginfo_t lastinfo;
366         int error = -ESRCH;
367
368         read_lock(&tasklist_lock);
369         if (likely(child->sighand != NULL)) {
370                 error = -EINVAL;
371                 spin_lock_irq(&child->sighand->siglock);
372                 if (likely(child->last_siginfo != NULL)) {
373                         lastinfo = *child->last_siginfo;
374                         error = 0;
375                 }
376                 spin_unlock_irq(&child->sighand->siglock);
377         }
378         read_unlock(&tasklist_lock);
379         if (!error)
380                 return copy_siginfo_to_user(data, &lastinfo);
381         return error;
382 }
383
384 static int ptrace_setsiginfo(struct task_struct *child, siginfo_t __user * data)
385 {
386         siginfo_t newinfo;
387         int error = -ESRCH;
388
389         if (copy_from_user(&newinfo, data, sizeof (siginfo_t)))
390                 return -EFAULT;
391
392         read_lock(&tasklist_lock);
393         if (likely(child->sighand != NULL)) {
394                 error = -EINVAL;
395                 spin_lock_irq(&child->sighand->siglock);
396                 if (likely(child->last_siginfo != NULL)) {
397                         *child->last_siginfo = newinfo;
398                         error = 0;
399                 }
400                 spin_unlock_irq(&child->sighand->siglock);
401         }
402         read_unlock(&tasklist_lock);
403         return error;
404 }
405
406 int ptrace_request(struct task_struct *child, long request,
407                    long addr, long data)
408 {
409         int ret = -EIO;
410
411         switch (request) {
412 #ifdef PTRACE_OLDSETOPTIONS
413         case PTRACE_OLDSETOPTIONS:
414 #endif
415         case PTRACE_SETOPTIONS:
416                 ret = ptrace_setoptions(child, data);
417                 break;
418         case PTRACE_GETEVENTMSG:
419                 ret = put_user(child->ptrace_message, (unsigned long __user *) data);
420                 break;
421         case PTRACE_GETSIGINFO:
422                 ret = ptrace_getsiginfo(child, (siginfo_t __user *) data);
423                 break;
424         case PTRACE_SETSIGINFO:
425                 ret = ptrace_setsiginfo(child, (siginfo_t __user *) data);
426                 break;
427         default:
428                 break;
429         }
430
431         return ret;
432 }
433
434 /**
435  * ptrace_traceme  --  helper for PTRACE_TRACEME
436  *
437  * Performs checks and sets PT_PTRACED.
438  * Should be used by all ptrace implementations for PTRACE_TRACEME.
439  */
440 int ptrace_traceme(void)
441 {
442         int ret = -EPERM;
443
444         /*
445          * Are we already being traced?
446          */
447         task_lock(current);
448         if (!(current->ptrace & PT_PTRACED)) {
449                 ret = security_ptrace(current->parent, current);
450                 /*
451                  * Set the ptrace bit in the process ptrace flags.
452                  */
453                 if (!ret)
454                         current->ptrace |= PT_PTRACED;
455         }
456         task_unlock(current);
457         return ret;
458 }
459
460 /**
461  * ptrace_get_task_struct  --  grab a task struct reference for ptrace
462  * @pid:       process id to grab a task_struct reference of
463  *
464  * This function is a helper for ptrace implementations.  It checks
465  * permissions and then grabs a task struct for use of the actual
466  * ptrace implementation.
467  *
468  * Returns the task_struct for @pid or an ERR_PTR() on failure.
469  */
470 struct task_struct *ptrace_get_task_struct(pid_t pid)
471 {
472         struct task_struct *child;
473
474         /*
475          * Tracing init is not allowed.
476          */
477         if (pid == 1)
478                 return ERR_PTR(-EPERM);
479
480         read_lock(&tasklist_lock);
481         child = find_task_by_pid(pid);
482         if (child)
483                 get_task_struct(child);
484         read_unlock(&tasklist_lock);
485         if (!child)
486                 return ERR_PTR(-ESRCH);
487         return child;
488 }
489
490 #ifndef __ARCH_SYS_PTRACE
491 asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
492 {
493         struct task_struct *child;
494         long ret;
495
496         /*
497          * This lock_kernel fixes a subtle race with suid exec
498          */
499         lock_kernel();
500         if (request == PTRACE_TRACEME) {
501                 ret = ptrace_traceme();
502                 goto out;
503         }
504
505         child = ptrace_get_task_struct(pid);
506         if (IS_ERR(child)) {
507                 ret = PTR_ERR(child);
508                 goto out;
509         }
510
511         ret = -EPERM;
512         if (!vx_check(vx_task_xid(child), VX_WATCH|VX_IDENT))
513                 goto out_put_task_struct;
514
515         if (request == PTRACE_ATTACH) {
516                 ret = ptrace_attach(child);
517                 goto out_put_task_struct;
518         }
519
520         ret = ptrace_check_attach(child, request == PTRACE_KILL);
521         if (ret < 0)
522                 goto out_put_task_struct;
523
524         ret = arch_ptrace(child, request, addr, data);
525         if (ret < 0)
526                 goto out_put_task_struct;
527
528  out_put_task_struct:
529         put_task_struct(child);
530  out:
531         unlock_kernel();
532         return ret;
533 }
534 #endif /* __ARCH_SYS_PTRACE */