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