CRED: Constify the kernel_cap_t arguments to the capset LSM hooks
[GitHub/mt8127/android_kernel_alcatel_ttab.git] / kernel / ptrace.c
CommitLineData
1da177e4
LT
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
c59ede7b 10#include <linux/capability.h>
1da177e4
LT
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>
7ed20e1a 20#include <linux/signal.h>
a5cb013d 21#include <linux/audit.h>
b488893a 22#include <linux/pid_namespace.h>
f17d30a8 23#include <linux/syscalls.h>
1da177e4
LT
24
25#include <asm/pgtable.h>
26#include <asm/uaccess.h>
27
28/*
29 * ptrace a task: make the debugger its new parent and
30 * move it to the ptrace list.
31 *
32 * Must be called with the tasklist lock write-held.
33 */
36c8b586 34void __ptrace_link(struct task_struct *child, struct task_struct *new_parent)
1da177e4 35{
f470021a
RM
36 BUG_ON(!list_empty(&child->ptrace_entry));
37 list_add(&child->ptrace_entry, &new_parent->ptraced);
1da177e4 38 child->parent = new_parent;
1da177e4
LT
39}
40
41/*
42 * Turn a tracing stop into a normal stop now, since with no tracer there
43 * would be no way to wake it up with SIGCONT or SIGKILL. If there was a
44 * signal sent that would resume the child, but didn't because it was in
45 * TASK_TRACED, resume it now.
46 * Requires that irqs be disabled.
47 */
b747c8c1 48static void ptrace_untrace(struct task_struct *child)
1da177e4
LT
49{
50 spin_lock(&child->sighand->siglock);
6618a3e2 51 if (task_is_traced(child)) {
1da177e4 52 if (child->signal->flags & SIGNAL_STOP_STOPPED) {
d9ae90ac 53 __set_task_state(child, TASK_STOPPED);
1da177e4
LT
54 } else {
55 signal_wake_up(child, 1);
56 }
57 }
58 spin_unlock(&child->sighand->siglock);
59}
60
61/*
62 * unptrace a task: move it back to its original parent and
63 * remove it from the ptrace list.
64 *
65 * Must be called with the tasklist lock write-held.
66 */
36c8b586 67void __ptrace_unlink(struct task_struct *child)
1da177e4 68{
5ecfbae0
ON
69 BUG_ON(!child->ptrace);
70
1da177e4 71 child->ptrace = 0;
f470021a
RM
72 child->parent = child->real_parent;
73 list_del_init(&child->ptrace_entry);
1da177e4 74
6618a3e2 75 if (task_is_traced(child))
e57a5059 76 ptrace_untrace(child);
1da177e4
LT
77}
78
79/*
80 * Check that we have indeed attached to the thing..
81 */
82int ptrace_check_attach(struct task_struct *child, int kill)
83{
84 int ret = -ESRCH;
85
86 /*
87 * We take the read lock around doing both checks to close a
88 * possible race where someone else was tracing our child and
89 * detached between these two checks. After this locked check,
90 * we are sure that this is our traced child and that can only
91 * be changed by us so it's not changing right after this.
92 */
93 read_lock(&tasklist_lock);
c0c0b649 94 if ((child->ptrace & PT_PTRACED) && child->parent == current) {
1da177e4 95 ret = 0;
c0c0b649
ON
96 /*
97 * child->sighand can't be NULL, release_task()
98 * does ptrace_unlink() before __exit_signal().
99 */
1da177e4 100 spin_lock_irq(&child->sighand->siglock);
d9ae90ac 101 if (task_is_stopped(child))
1da177e4 102 child->state = TASK_TRACED;
d9ae90ac 103 else if (!task_is_traced(child) && !kill)
1da177e4 104 ret = -ESRCH;
1da177e4
LT
105 spin_unlock_irq(&child->sighand->siglock);
106 }
107 read_unlock(&tasklist_lock);
108
d9ae90ac 109 if (!ret && !kill)
85ba2d86 110 ret = wait_task_inactive(child, TASK_TRACED) ? 0 : -ESRCH;
1da177e4
LT
111
112 /* All systems go.. */
113 return ret;
114}
115
006ebb40 116int __ptrace_may_access(struct task_struct *task, unsigned int mode)
ab8d11be 117{
df26c40e
EB
118 /* May we inspect the given task?
119 * This check is used both for attaching with ptrace
120 * and for allowing access to sensitive information in /proc.
121 *
122 * ptrace_attach denies several cases that /proc allows
123 * because setting up the necessary parent/child relationship
124 * or halting the specified task is impossible.
125 */
76aac0e9
DH
126 uid_t uid;
127 gid_t gid;
df26c40e
EB
128 int dumpable = 0;
129 /* Don't let security modules deny introspection */
130 if (task == current)
131 return 0;
76aac0e9
DH
132 current_uid_gid(&uid, &gid);
133 if ((uid != task->euid ||
134 uid != task->suid ||
135 uid != task->uid ||
136 gid != task->egid ||
137 gid != task->sgid ||
138 gid != task->gid) && !capable(CAP_SYS_PTRACE))
ab8d11be
MS
139 return -EPERM;
140 smp_rmb();
df26c40e 141 if (task->mm)
6c5d5238 142 dumpable = get_dumpable(task->mm);
df26c40e 143 if (!dumpable && !capable(CAP_SYS_PTRACE))
ab8d11be
MS
144 return -EPERM;
145
5cd9c58f 146 return security_ptrace_may_access(task, mode);
ab8d11be
MS
147}
148
006ebb40 149bool ptrace_may_access(struct task_struct *task, unsigned int mode)
ab8d11be
MS
150{
151 int err;
152 task_lock(task);
006ebb40 153 err = __ptrace_may_access(task, mode);
ab8d11be 154 task_unlock(task);
006ebb40 155 return (!err ? true : false);
ab8d11be
MS
156}
157
1da177e4
LT
158int ptrace_attach(struct task_struct *task)
159{
160 int retval;
6175ecfe 161 unsigned long flags;
f5b40e36 162
a5cb013d
AV
163 audit_ptrace(task);
164
1da177e4 165 retval = -EPERM;
bac0abd6 166 if (same_thread_group(task, current))
f5b40e36
LT
167 goto out;
168
f358166a
LT
169repeat:
170 /*
171 * Nasty, nasty.
172 *
173 * We want to hold both the task-lock and the
174 * tasklist_lock for writing at the same time.
175 * But that's against the rules (tasklist_lock
176 * is taken for reading by interrupts on other
177 * cpu's that may have task_lock).
178 */
f5b40e36 179 task_lock(task);
6175ecfe 180 if (!write_trylock_irqsave(&tasklist_lock, flags)) {
f358166a
LT
181 task_unlock(task);
182 do {
183 cpu_relax();
184 } while (!write_can_lock(&tasklist_lock));
185 goto repeat;
186 }
f5b40e36 187
df26c40e
EB
188 if (!task->mm)
189 goto bad;
1da177e4
LT
190 /* the same process cannot be attached many times */
191 if (task->ptrace & PT_PTRACED)
192 goto bad;
006ebb40 193 retval = __ptrace_may_access(task, PTRACE_MODE_ATTACH);
1da177e4
LT
194 if (retval)
195 goto bad;
196
197 /* Go */
6b39c7bf 198 task->ptrace |= PT_PTRACED;
1da177e4
LT
199 if (capable(CAP_SYS_PTRACE))
200 task->ptrace |= PT_PTRACE_CAP;
1da177e4 201
1da177e4 202 __ptrace_link(task, current);
1da177e4 203
33e9fc7d 204 send_sig_info(SIGSTOP, SEND_SIG_FORCED, task);
1da177e4 205bad:
6175ecfe 206 write_unlock_irqrestore(&tasklist_lock, flags);
1da177e4 207 task_unlock(task);
f5b40e36 208out:
1da177e4
LT
209 return retval;
210}
211
d5f70c00 212static inline void __ptrace_detach(struct task_struct *child, unsigned int data)
5ecfbae0
ON
213{
214 child->exit_code = data;
215 /* .. re-parent .. */
216 __ptrace_unlink(child);
217 /* .. and wake it up. */
218 if (child->exit_state != EXIT_ZOMBIE)
219 wake_up_process(child);
220}
221
1da177e4
LT
222int ptrace_detach(struct task_struct *child, unsigned int data)
223{
7ed20e1a 224 if (!valid_signal(data))
5ecfbae0 225 return -EIO;
1da177e4
LT
226
227 /* Architecture-specific hardware disable .. */
228 ptrace_disable(child);
7d941432 229 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
1da177e4 230
1da177e4 231 write_lock_irq(&tasklist_lock);
d5f70c00 232 /* protect against de_thread()->release_task() */
5ecfbae0
ON
233 if (child->ptrace)
234 __ptrace_detach(child, data);
1da177e4
LT
235 write_unlock_irq(&tasklist_lock);
236
237 return 0;
238}
239
1da177e4
LT
240int ptrace_readdata(struct task_struct *tsk, unsigned long src, char __user *dst, int len)
241{
242 int copied = 0;
243
244 while (len > 0) {
245 char buf[128];
246 int this_len, retval;
247
248 this_len = (len > sizeof(buf)) ? sizeof(buf) : len;
249 retval = access_process_vm(tsk, src, buf, this_len, 0);
250 if (!retval) {
251 if (copied)
252 break;
253 return -EIO;
254 }
255 if (copy_to_user(dst, buf, retval))
256 return -EFAULT;
257 copied += retval;
258 src += retval;
259 dst += retval;
260 len -= retval;
261 }
262 return copied;
263}
264
265int ptrace_writedata(struct task_struct *tsk, char __user *src, unsigned long dst, int len)
266{
267 int copied = 0;
268
269 while (len > 0) {
270 char buf[128];
271 int this_len, retval;
272
273 this_len = (len > sizeof(buf)) ? sizeof(buf) : len;
274 if (copy_from_user(buf, src, this_len))
275 return -EFAULT;
276 retval = access_process_vm(tsk, dst, buf, this_len, 1);
277 if (!retval) {
278 if (copied)
279 break;
280 return -EIO;
281 }
282 copied += retval;
283 src += retval;
284 dst += retval;
285 len -= retval;
286 }
287 return copied;
288}
289
290static int ptrace_setoptions(struct task_struct *child, long data)
291{
292 child->ptrace &= ~PT_TRACE_MASK;
293
294 if (data & PTRACE_O_TRACESYSGOOD)
295 child->ptrace |= PT_TRACESYSGOOD;
296
297 if (data & PTRACE_O_TRACEFORK)
298 child->ptrace |= PT_TRACE_FORK;
299
300 if (data & PTRACE_O_TRACEVFORK)
301 child->ptrace |= PT_TRACE_VFORK;
302
303 if (data & PTRACE_O_TRACECLONE)
304 child->ptrace |= PT_TRACE_CLONE;
305
306 if (data & PTRACE_O_TRACEEXEC)
307 child->ptrace |= PT_TRACE_EXEC;
308
309 if (data & PTRACE_O_TRACEVFORKDONE)
310 child->ptrace |= PT_TRACE_VFORK_DONE;
311
312 if (data & PTRACE_O_TRACEEXIT)
313 child->ptrace |= PT_TRACE_EXIT;
314
315 return (data & ~PTRACE_O_MASK) ? -EINVAL : 0;
316}
317
e16b2781 318static int ptrace_getsiginfo(struct task_struct *child, siginfo_t *info)
1da177e4 319{
1da177e4
LT
320 int error = -ESRCH;
321
322 read_lock(&tasklist_lock);
323 if (likely(child->sighand != NULL)) {
324 error = -EINVAL;
325 spin_lock_irq(&child->sighand->siglock);
326 if (likely(child->last_siginfo != NULL)) {
e16b2781 327 *info = *child->last_siginfo;
1da177e4
LT
328 error = 0;
329 }
330 spin_unlock_irq(&child->sighand->siglock);
331 }
332 read_unlock(&tasklist_lock);
1da177e4
LT
333 return error;
334}
335
e16b2781 336static int ptrace_setsiginfo(struct task_struct *child, const siginfo_t *info)
1da177e4 337{
1da177e4
LT
338 int error = -ESRCH;
339
1da177e4
LT
340 read_lock(&tasklist_lock);
341 if (likely(child->sighand != NULL)) {
342 error = -EINVAL;
343 spin_lock_irq(&child->sighand->siglock);
344 if (likely(child->last_siginfo != NULL)) {
e16b2781 345 *child->last_siginfo = *info;
1da177e4
LT
346 error = 0;
347 }
348 spin_unlock_irq(&child->sighand->siglock);
349 }
350 read_unlock(&tasklist_lock);
351 return error;
352}
353
36df29d7
RM
354
355#ifdef PTRACE_SINGLESTEP
356#define is_singlestep(request) ((request) == PTRACE_SINGLESTEP)
357#else
358#define is_singlestep(request) 0
359#endif
360
5b88abbf
RM
361#ifdef PTRACE_SINGLEBLOCK
362#define is_singleblock(request) ((request) == PTRACE_SINGLEBLOCK)
363#else
364#define is_singleblock(request) 0
365#endif
366
36df29d7
RM
367#ifdef PTRACE_SYSEMU
368#define is_sysemu_singlestep(request) ((request) == PTRACE_SYSEMU_SINGLESTEP)
369#else
370#define is_sysemu_singlestep(request) 0
371#endif
372
373static int ptrace_resume(struct task_struct *child, long request, long data)
374{
375 if (!valid_signal(data))
376 return -EIO;
377
378 if (request == PTRACE_SYSCALL)
379 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
380 else
381 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
382
383#ifdef TIF_SYSCALL_EMU
384 if (request == PTRACE_SYSEMU || request == PTRACE_SYSEMU_SINGLESTEP)
385 set_tsk_thread_flag(child, TIF_SYSCALL_EMU);
386 else
387 clear_tsk_thread_flag(child, TIF_SYSCALL_EMU);
388#endif
389
5b88abbf
RM
390 if (is_singleblock(request)) {
391 if (unlikely(!arch_has_block_step()))
392 return -EIO;
393 user_enable_block_step(child);
394 } else if (is_singlestep(request) || is_sysemu_singlestep(request)) {
36df29d7
RM
395 if (unlikely(!arch_has_single_step()))
396 return -EIO;
397 user_enable_single_step(child);
398 }
399 else
400 user_disable_single_step(child);
401
402 child->exit_code = data;
403 wake_up_process(child);
404
405 return 0;
406}
407
1da177e4
LT
408int ptrace_request(struct task_struct *child, long request,
409 long addr, long data)
410{
411 int ret = -EIO;
e16b2781 412 siginfo_t siginfo;
1da177e4
LT
413
414 switch (request) {
16c3e389
RM
415 case PTRACE_PEEKTEXT:
416 case PTRACE_PEEKDATA:
417 return generic_ptrace_peekdata(child, addr, data);
418 case PTRACE_POKETEXT:
419 case PTRACE_POKEDATA:
420 return generic_ptrace_pokedata(child, addr, data);
421
1da177e4
LT
422#ifdef PTRACE_OLDSETOPTIONS
423 case PTRACE_OLDSETOPTIONS:
424#endif
425 case PTRACE_SETOPTIONS:
426 ret = ptrace_setoptions(child, data);
427 break;
428 case PTRACE_GETEVENTMSG:
429 ret = put_user(child->ptrace_message, (unsigned long __user *) data);
430 break;
e16b2781 431
1da177e4 432 case PTRACE_GETSIGINFO:
e16b2781
RM
433 ret = ptrace_getsiginfo(child, &siginfo);
434 if (!ret)
435 ret = copy_siginfo_to_user((siginfo_t __user *) data,
436 &siginfo);
1da177e4 437 break;
e16b2781 438
1da177e4 439 case PTRACE_SETSIGINFO:
e16b2781
RM
440 if (copy_from_user(&siginfo, (siginfo_t __user *) data,
441 sizeof siginfo))
442 ret = -EFAULT;
443 else
444 ret = ptrace_setsiginfo(child, &siginfo);
1da177e4 445 break;
e16b2781 446
1bcf5482
AD
447 case PTRACE_DETACH: /* detach a process that was attached. */
448 ret = ptrace_detach(child, data);
449 break;
36df29d7
RM
450
451#ifdef PTRACE_SINGLESTEP
452 case PTRACE_SINGLESTEP:
453#endif
5b88abbf
RM
454#ifdef PTRACE_SINGLEBLOCK
455 case PTRACE_SINGLEBLOCK:
456#endif
36df29d7
RM
457#ifdef PTRACE_SYSEMU
458 case PTRACE_SYSEMU:
459 case PTRACE_SYSEMU_SINGLESTEP:
460#endif
461 case PTRACE_SYSCALL:
462 case PTRACE_CONT:
463 return ptrace_resume(child, request, data);
464
465 case PTRACE_KILL:
466 if (child->exit_state) /* already dead */
467 return 0;
468 return ptrace_resume(child, request, SIGKILL);
469
1da177e4
LT
470 default:
471 break;
472 }
473
474 return ret;
475}
481bed45 476
6b9c7ed8
CH
477/**
478 * ptrace_traceme -- helper for PTRACE_TRACEME
479 *
480 * Performs checks and sets PT_PTRACED.
481 * Should be used by all ptrace implementations for PTRACE_TRACEME.
482 */
483int ptrace_traceme(void)
481bed45 484{
f5b40e36 485 int ret = -EPERM;
481bed45
CH
486
487 /*
6b9c7ed8
CH
488 * Are we already being traced?
489 */
f470021a 490repeat:
f5b40e36
LT
491 task_lock(current);
492 if (!(current->ptrace & PT_PTRACED)) {
f470021a
RM
493 /*
494 * See ptrace_attach() comments about the locking here.
495 */
496 unsigned long flags;
497 if (!write_trylock_irqsave(&tasklist_lock, flags)) {
498 task_unlock(current);
499 do {
500 cpu_relax();
501 } while (!write_can_lock(&tasklist_lock));
502 goto repeat;
503 }
504
5cd9c58f 505 ret = security_ptrace_traceme(current->parent);
f470021a 506
f5b40e36
LT
507 /*
508 * Set the ptrace bit in the process ptrace flags.
f470021a 509 * Then link us on our parent's ptraced list.
f5b40e36 510 */
f470021a 511 if (!ret) {
f5b40e36 512 current->ptrace |= PT_PTRACED;
f470021a
RM
513 __ptrace_link(current, current->real_parent);
514 }
515
516 write_unlock_irqrestore(&tasklist_lock, flags);
f5b40e36
LT
517 }
518 task_unlock(current);
519 return ret;
6b9c7ed8 520}
481bed45 521
6b9c7ed8
CH
522/**
523 * ptrace_get_task_struct -- grab a task struct reference for ptrace
524 * @pid: process id to grab a task_struct reference of
525 *
526 * This function is a helper for ptrace implementations. It checks
527 * permissions and then grabs a task struct for use of the actual
528 * ptrace implementation.
529 *
530 * Returns the task_struct for @pid or an ERR_PTR() on failure.
531 */
532struct task_struct *ptrace_get_task_struct(pid_t pid)
533{
534 struct task_struct *child;
481bed45 535
481bed45 536 read_lock(&tasklist_lock);
228ebcbe 537 child = find_task_by_vpid(pid);
481bed45
CH
538 if (child)
539 get_task_struct(child);
f400e198 540
481bed45
CH
541 read_unlock(&tasklist_lock);
542 if (!child)
6b9c7ed8
CH
543 return ERR_PTR(-ESRCH);
544 return child;
481bed45
CH
545}
546
0ac15559
CH
547#ifndef arch_ptrace_attach
548#define arch_ptrace_attach(child) do { } while (0)
549#endif
550
481bed45
CH
551asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
552{
553 struct task_struct *child;
554 long ret;
555
556 /*
557 * This lock_kernel fixes a subtle race with suid exec
558 */
559 lock_kernel();
6b9c7ed8
CH
560 if (request == PTRACE_TRACEME) {
561 ret = ptrace_traceme();
6ea6dd93
HS
562 if (!ret)
563 arch_ptrace_attach(current);
481bed45 564 goto out;
6b9c7ed8
CH
565 }
566
567 child = ptrace_get_task_struct(pid);
568 if (IS_ERR(child)) {
569 ret = PTR_ERR(child);
570 goto out;
571 }
481bed45
CH
572
573 if (request == PTRACE_ATTACH) {
574 ret = ptrace_attach(child);
0ac15559
CH
575 /*
576 * Some architectures need to do book-keeping after
577 * a ptrace attach.
578 */
579 if (!ret)
580 arch_ptrace_attach(child);
005f18df 581 goto out_put_task_struct;
481bed45
CH
582 }
583
584 ret = ptrace_check_attach(child, request == PTRACE_KILL);
585 if (ret < 0)
586 goto out_put_task_struct;
587
588 ret = arch_ptrace(child, request, addr, data);
589 if (ret < 0)
590 goto out_put_task_struct;
591
592 out_put_task_struct:
593 put_task_struct(child);
594 out:
595 unlock_kernel();
596 return ret;
597}
76647323
AD
598
599int generic_ptrace_peekdata(struct task_struct *tsk, long addr, long data)
600{
601 unsigned long tmp;
602 int copied;
603
604 copied = access_process_vm(tsk, addr, &tmp, sizeof(tmp), 0);
605 if (copied != sizeof(tmp))
606 return -EIO;
607 return put_user(tmp, (unsigned long __user *)data);
608}
f284ce72
AD
609
610int generic_ptrace_pokedata(struct task_struct *tsk, long addr, long data)
611{
612 int copied;
613
614 copied = access_process_vm(tsk, addr, &data, sizeof(data), 1);
615 return (copied == sizeof(data)) ? 0 : -EIO;
616}
032d82d9 617
9d04d928 618#if defined CONFIG_COMPAT && defined __ARCH_WANT_COMPAT_SYS_PTRACE
032d82d9
RM
619#include <linux/compat.h>
620
621int compat_ptrace_request(struct task_struct *child, compat_long_t request,
622 compat_ulong_t addr, compat_ulong_t data)
623{
624 compat_ulong_t __user *datap = compat_ptr(data);
625 compat_ulong_t word;
e16b2781 626 siginfo_t siginfo;
032d82d9
RM
627 int ret;
628
629 switch (request) {
630 case PTRACE_PEEKTEXT:
631 case PTRACE_PEEKDATA:
632 ret = access_process_vm(child, addr, &word, sizeof(word), 0);
633 if (ret != sizeof(word))
634 ret = -EIO;
635 else
636 ret = put_user(word, datap);
637 break;
638
639 case PTRACE_POKETEXT:
640 case PTRACE_POKEDATA:
641 ret = access_process_vm(child, addr, &data, sizeof(data), 1);
642 ret = (ret != sizeof(data) ? -EIO : 0);
643 break;
644
645 case PTRACE_GETEVENTMSG:
646 ret = put_user((compat_ulong_t) child->ptrace_message, datap);
647 break;
648
e16b2781
RM
649 case PTRACE_GETSIGINFO:
650 ret = ptrace_getsiginfo(child, &siginfo);
651 if (!ret)
652 ret = copy_siginfo_to_user32(
653 (struct compat_siginfo __user *) datap,
654 &siginfo);
655 break;
656
657 case PTRACE_SETSIGINFO:
658 memset(&siginfo, 0, sizeof siginfo);
659 if (copy_siginfo_from_user32(
660 &siginfo, (struct compat_siginfo __user *) datap))
661 ret = -EFAULT;
662 else
663 ret = ptrace_setsiginfo(child, &siginfo);
664 break;
665
032d82d9
RM
666 default:
667 ret = ptrace_request(child, request, addr, data);
668 }
669
670 return ret;
671}
c269f196 672
c269f196
RM
673asmlinkage long compat_sys_ptrace(compat_long_t request, compat_long_t pid,
674 compat_long_t addr, compat_long_t data)
675{
676 struct task_struct *child;
677 long ret;
678
679 /*
680 * This lock_kernel fixes a subtle race with suid exec
681 */
682 lock_kernel();
683 if (request == PTRACE_TRACEME) {
684 ret = ptrace_traceme();
685 goto out;
686 }
687
688 child = ptrace_get_task_struct(pid);
689 if (IS_ERR(child)) {
690 ret = PTR_ERR(child);
691 goto out;
692 }
693
694 if (request == PTRACE_ATTACH) {
695 ret = ptrace_attach(child);
696 /*
697 * Some architectures need to do book-keeping after
698 * a ptrace attach.
699 */
700 if (!ret)
701 arch_ptrace_attach(child);
702 goto out_put_task_struct;
703 }
704
705 ret = ptrace_check_attach(child, request == PTRACE_KILL);
706 if (!ret)
707 ret = compat_arch_ptrace(child, request, addr, data);
708
709 out_put_task_struct:
710 put_task_struct(child);
711 out:
712 unlock_kernel();
713 return ret;
714}
9d04d928 715#endif /* CONFIG_COMPAT && __ARCH_WANT_COMPAT_SYS_PTRACE */