This commit was manufactured by cvs2svn to create branch
[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/module.h>
11 #include <linux/sched.h>
12 #include <linux/errno.h>
13 #include <linux/mm.h>
14 #include <linux/highmem.h>
15 #include <linux/pagemap.h>
16 #include <linux/smp_lock.h>
17 #include <linux/ptrace.h>
18 #include <linux/security.h>
19
20 #include <asm/pgtable.h>
21 #include <asm/uaccess.h>
22
23 /*
24  * ptrace a task: make the debugger its new parent and
25  * move it to the ptrace list.
26  *
27  * Must be called with the tasklist lock write-held.
28  */
29 void __ptrace_link(task_t *child, task_t *new_parent)
30 {
31         if (!list_empty(&child->ptrace_list))
32                 BUG();
33         if (child->parent == new_parent)
34                 return;
35         list_add(&child->ptrace_list, &child->parent->ptrace_children);
36         REMOVE_LINKS(child);
37         child->parent = new_parent;
38         SET_LINKS(child);
39 }
40  
41 static inline int pending_resume_signal(struct sigpending *pending)
42 {
43 #define M(sig) (1UL << ((sig)-1))
44         return sigtestsetmask(&pending->signal, M(SIGCONT) | M(SIGKILL));
45 }
46
47 /*
48  * Turn a tracing stop into a normal stop now, since with no tracer there
49  * would be no way to wake it up with SIGCONT or SIGKILL.  If there was a
50  * signal sent that would resume the child, but didn't because it was in
51  * TASK_TRACED, resume it now.
52  */
53 void ptrace_untrace(task_t *child)
54 {
55         spin_lock(&child->sighand->siglock);
56         child->state = TASK_STOPPED;
57         if (pending_resume_signal(&child->pending) ||
58             pending_resume_signal(&child->signal->shared_pending)) {
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  *
68  * Must be called with the tasklist lock write-held.
69  */
70 void __ptrace_unlink(task_t *child)
71 {
72         if (!child->ptrace)
73                 BUG();
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 int ptrace_attach(struct task_struct *task)
124 {
125         int retval;
126         task_lock(task);
127         retval = -EPERM;
128         if (task->pid <= 1)
129                 goto bad;
130         if (task == current)
131                 goto bad;
132         if (!task->mm)
133                 goto bad;
134         if(((current->uid != task->euid) ||
135             (current->uid != task->suid) ||
136             (current->uid != task->uid) ||
137             (current->gid != task->egid) ||
138             (current->gid != task->sgid) ||
139             (current->gid != task->gid)) && !capable(CAP_SYS_PTRACE))
140                 goto bad;
141         rmb();
142         if (!task->mm->dumpable && !capable(CAP_SYS_PTRACE))
143                 goto bad;
144         /* the same process cannot be attached many times */
145         if (task->ptrace & PT_PTRACED)
146                 goto bad;
147         retval = security_ptrace(current, task);
148         if (retval)
149                 goto bad;
150
151         /* Go */
152         task->ptrace |= PT_PTRACED | ((task->real_parent != current)
153                                       ? PT_ATTACHED : 0);
154         if (capable(CAP_SYS_PTRACE))
155                 task->ptrace |= PT_PTRACE_CAP;
156         task_unlock(task);
157
158         write_lock_irq(&tasklist_lock);
159         __ptrace_link(task, current);
160         write_unlock_irq(&tasklist_lock);
161
162         force_sig_specific(SIGSTOP, task);
163         return 0;
164
165 bad:
166         task_unlock(task);
167         return retval;
168 }
169
170 int ptrace_detach(struct task_struct *child, unsigned int data)
171 {
172         if ((unsigned long) data > _NSIG)
173                 return  -EIO;
174
175         /* Architecture-specific hardware disable .. */
176         ptrace_disable(child);
177
178         /* .. re-parent .. */
179         child->exit_code = data;
180
181         write_lock_irq(&tasklist_lock);
182         __ptrace_unlink(child);
183         /* .. and wake it up. */
184         if (child->exit_state != EXIT_ZOMBIE)
185                 wake_up_process(child);
186         write_unlock_irq(&tasklist_lock);
187
188         return 0;
189 }
190
191 /*
192  * Access another process' address space.
193  * Source/target buffer must be kernel space, 
194  * Do not walk the page table directly, use get_user_pages
195  */
196
197 int access_process_vm(struct task_struct *tsk, unsigned long addr, void *buf, int len, int write)
198 {
199         struct mm_struct *mm;
200         struct vm_area_struct *vma;
201         struct page *page;
202         void *old_buf = buf;
203
204         mm = get_task_mm(tsk);
205         if (!mm)
206                 return 0;
207
208         down_read(&mm->mmap_sem);
209         /* ignore errors, just check how much was sucessfully transfered */
210         while (len) {
211                 int bytes, ret, offset;
212                 void *maddr;
213
214                 ret = get_user_pages(tsk, mm, addr, 1,
215                                 write, 1, &page, &vma);
216                 if (ret <= 0)
217                         break;
218
219                 bytes = len;
220                 offset = addr & (PAGE_SIZE-1);
221                 if (bytes > PAGE_SIZE-offset)
222                         bytes = PAGE_SIZE-offset;
223
224                 maddr = kmap(page);
225                 if (write) {
226                         copy_to_user_page(vma, page, addr,
227                                           maddr + offset, buf, bytes);
228                         set_page_dirty_lock(page);
229                 } else {
230                         copy_from_user_page(vma, page, addr,
231                                             buf, maddr + offset, bytes);
232                 }
233                 kunmap(page);
234                 page_cache_release(page);
235                 len -= bytes;
236                 buf += bytes;
237                 addr += bytes;
238         }
239         up_read(&mm->mmap_sem);
240         mmput(mm);
241         
242         return buf - old_buf;
243 }
244
245 int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len)
246 {
247         int copied = 0;
248
249         while (len > 0) {
250                 char buf[128];
251                 int this_len, retval;
252
253                 this_len = (len > sizeof(buf)) ? sizeof(buf) : len;
254                 retval = access_process_vm(tsk, src, buf, this_len, 0);
255                 if (!retval) {
256                         if (copied)
257                                 break;
258                         return -EIO;
259                 }
260                 if (copy_to_user(dst, buf, retval))
261                         return -EFAULT;
262                 copied += retval;
263                 src += retval;
264                 dst += retval;
265                 len -= retval;                  
266         }
267         return copied;
268 }
269
270 int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int len)
271 {
272         int copied = 0;
273
274         while (len > 0) {
275                 char buf[128];
276                 int this_len, retval;
277
278                 this_len = (len > sizeof(buf)) ? sizeof(buf) : len;
279                 if (copy_from_user(buf, src, this_len))
280                         return -EFAULT;
281                 retval = access_process_vm(tsk, dst, buf, this_len, 1);
282                 if (!retval) {
283                         if (copied)
284                                 break;
285                         return -EIO;
286                 }
287                 copied += retval;
288                 src += retval;
289                 dst += retval;
290                 len -= retval;                  
291         }
292         return copied;
293 }
294
295 static int ptrace_setoptions(struct task_struct *child, long data)
296 {
297         child->ptrace &= ~PT_TRACE_MASK;
298
299         if (data & PTRACE_O_TRACESYSGOOD)
300                 child->ptrace |= PT_TRACESYSGOOD;
301
302         if (data & PTRACE_O_TRACEFORK)
303                 child->ptrace |= PT_TRACE_FORK;
304
305         if (data & PTRACE_O_TRACEVFORK)
306                 child->ptrace |= PT_TRACE_VFORK;
307
308         if (data & PTRACE_O_TRACECLONE)
309                 child->ptrace |= PT_TRACE_CLONE;
310
311         if (data & PTRACE_O_TRACEEXEC)
312                 child->ptrace |= PT_TRACE_EXEC;
313
314         if (data & PTRACE_O_TRACEVFORKDONE)
315                 child->ptrace |= PT_TRACE_VFORK_DONE;
316
317         if (data & PTRACE_O_TRACEEXIT)
318                 child->ptrace |= PT_TRACE_EXIT;
319
320         return (data & ~PTRACE_O_MASK) ? -EINVAL : 0;
321 }
322
323 static int ptrace_getsiginfo(struct task_struct *child, siginfo_t __user * data)
324 {
325         if (child->last_siginfo == NULL)
326                 return -EINVAL;
327         return copy_siginfo_to_user(data, child->last_siginfo);
328 }
329
330 static int ptrace_setsiginfo(struct task_struct *child, siginfo_t __user * data)
331 {
332         if (child->last_siginfo == NULL)
333                 return -EINVAL;
334         if (copy_from_user(child->last_siginfo, data, sizeof (siginfo_t)) != 0)
335                 return -EFAULT;
336         return 0;
337 }
338
339 int ptrace_request(struct task_struct *child, long request,
340                    long addr, long data)
341 {
342         int ret = -EIO;
343
344         switch (request) {
345 #ifdef PTRACE_OLDSETOPTIONS
346         case PTRACE_OLDSETOPTIONS:
347 #endif
348         case PTRACE_SETOPTIONS:
349                 ret = ptrace_setoptions(child, data);
350                 break;
351         case PTRACE_GETEVENTMSG:
352                 ret = put_user(child->ptrace_message, (unsigned long __user *) data);
353                 break;
354         case PTRACE_GETSIGINFO:
355                 ret = ptrace_getsiginfo(child, (siginfo_t __user *) data);
356                 break;
357         case PTRACE_SETSIGINFO:
358                 ret = ptrace_setsiginfo(child, (siginfo_t __user *) data);
359                 break;
360         default:
361                 break;
362         }
363
364         return ret;
365 }