Lines Matching +full:- +full:- +full:disable +full:- +full:seccomp

1 // SPDX-License-Identifier: GPL-2.0-only
54 if (!tsk->ptrace || in ptrace_access_vm()
55 (current != tsk->parent) || in ptrace_access_vm()
57 !ptracer_capable(tsk, mm->user_ns))) { in ptrace_access_vm()
72 BUG_ON(!list_empty(&child->ptrace_entry)); in __ptrace_link()
73 list_add(&child->ptrace_entry, &new_parent->ptraced); in __ptrace_link()
74 child->parent = new_parent; in __ptrace_link()
75 child->ptracer_cred = get_cred(ptracer_cred); in __ptrace_link()
82 * Must be called with the tasklist lock write-held.
90 * __ptrace_unlink - unlink ptracee and restore its execution state
97 * Unlinking can happen via two paths - explicit PTRACE_DETACH or ptracer
108 * it goes through TRACED -> RUNNING -> STOPPED transition which is similar
112 * re-attaches and performs a WNOHANG wait(2), it may fail.
120 BUG_ON(!child->ptrace); in __ptrace_unlink()
127 child->parent = child->real_parent; in __ptrace_unlink()
128 list_del_init(&child->ptrace_entry); in __ptrace_unlink()
129 old_cred = child->ptracer_cred; in __ptrace_unlink()
130 child->ptracer_cred = NULL; in __ptrace_unlink()
133 spin_lock(&child->sighand->siglock); in __ptrace_unlink()
134 child->ptrace = 0; in __ptrace_unlink()
146 if (!(child->flags & PF_EXITING) && in __ptrace_unlink()
147 (child->signal->flags & SIGNAL_STOP_STOPPED || in __ptrace_unlink()
148 child->signal->group_stop_count)) { in __ptrace_unlink()
149 child->jobctl |= JOBCTL_STOP_PENDING; in __ptrace_unlink()
158 if (!(child->jobctl & JOBCTL_STOP_SIGMASK)) in __ptrace_unlink()
159 child->jobctl |= SIGSTOP; in __ptrace_unlink()
168 if (child->jobctl & JOBCTL_STOP_PENDING || task_is_traced(child)) in __ptrace_unlink()
171 spin_unlock(&child->sighand->siglock); in __ptrace_unlink()
176 if (task->exit_code != ((PTRACE_EVENT_EXEC << 8) | SIGTRAP)) in looks_like_a_spurious_pid()
179 if (task_pid_vnr(task) == task->ptrace_message) in looks_like_a_spurious_pid()
200 if (task->jobctl & JOBCTL_LISTENING) in ptrace_freeze_traced()
203 spin_lock_irq(&task->sighand->siglock); in ptrace_freeze_traced()
206 task->jobctl |= JOBCTL_PTRACE_FROZEN; in ptrace_freeze_traced()
209 spin_unlock_irq(&task->sighand->siglock); in ptrace_freeze_traced()
224 task->jobctl &= ~JOBCTL_PTRACE_FROZEN; in ptrace_unfreeze_traced()
226 task->jobctl &= ~JOBCTL_TRACED; in ptrace_unfreeze_traced()
234 * ptrace_check_attach - check whether ptracee is ready for ptrace operation
245 * Grabs and releases tasklist_lock and @child->sighand->siglock.
248 * 0 on success, -ESRCH if %child is not ready.
252 int ret = -ESRCH; in ptrace_check_attach()
262 if (child->ptrace && child->parent == current) { in ptrace_check_attach()
264 * child->sighand can't be NULL, release_task() in ptrace_check_attach()
274 ret = -ESRCH; in ptrace_check_attach()
286 /* Returns 0 on success, -errno on denial. */
296 return -EPERM; in __ptrace_may_access()
313 caller_uid = cred->fsuid; in __ptrace_may_access()
314 caller_gid = cred->fsgid; in __ptrace_may_access()
324 caller_uid = cred->uid; in __ptrace_may_access()
325 caller_gid = cred->gid; in __ptrace_may_access()
328 if (uid_eq(caller_uid, tcred->euid) && in __ptrace_may_access()
329 uid_eq(caller_uid, tcred->suid) && in __ptrace_may_access()
330 uid_eq(caller_uid, tcred->uid) && in __ptrace_may_access()
331 gid_eq(caller_gid, tcred->egid) && in __ptrace_may_access()
332 gid_eq(caller_gid, tcred->sgid) && in __ptrace_may_access()
333 gid_eq(caller_gid, tcred->gid)) in __ptrace_may_access()
335 if (ptrace_has_cap(tcred->user_ns, mode)) in __ptrace_may_access()
338 return -EPERM; in __ptrace_may_access()
351 mm = task->mm; in __ptrace_may_access()
354 !ptrace_has_cap(mm->user_ns, mode))) in __ptrace_may_access()
355 return -EPERM; in __ptrace_may_access()
372 return -EINVAL; in check_ptrace_options()
377 return -EINVAL; in check_ptrace_options()
380 return -EPERM; in check_ptrace_options()
382 if (seccomp_mode(&current->seccomp) != SECCOMP_MODE_DISABLED || in check_ptrace_options()
383 current->ptrace & PT_SUSPEND_SECCOMP) in check_ptrace_options()
384 return -EPERM; in check_ptrace_options()
396 retval = -EIO; in ptrace_attach()
417 retval = -EPERM; in ptrace_attach()
418 if (unlikely(task->flags & PF_KTHREAD)) in ptrace_attach()
428 retval = -ERESTARTNOINTR; in ptrace_attach()
429 if (mutex_lock_interruptible(&task->signal->cred_guard_mutex)) in ptrace_attach()
439 retval = -EPERM; in ptrace_attach()
440 if (unlikely(task->exit_state)) in ptrace_attach()
442 if (task->ptrace) in ptrace_attach()
445 task->ptrace = flags; in ptrace_attach()
453 spin_lock(&task->sighand->siglock); in ptrace_attach()
463 * This hides STOPPED -> RUNNING -> TRACED transition from the in ptrace_attach()
474 task->jobctl &= ~JOBCTL_STOPPED; in ptrace_attach()
478 spin_unlock(&task->sighand->siglock); in ptrace_attach()
484 mutex_unlock(&task->signal->cred_guard_mutex); in ptrace_attach()
490 * not return to user-mode, it will exit and clear this bit in in ptrace_attach()
494 wait_on_bit(&task->jobctl, JOBCTL_TRAPPING_BIT, TASK_KILLABLE); in ptrace_attach()
502 * ptrace_traceme -- helper for PTRACE_TRACEME
509 int ret = -EPERM; in ptrace_traceme()
513 if (!current->ptrace) { in ptrace_traceme()
514 ret = security_ptrace_traceme(current->parent); in ptrace_traceme()
516 * Check PF_EXITING to ensure ->real_parent has not passed in ptrace_traceme()
518 * pretend ->real_parent untraces us right after return. in ptrace_traceme()
520 if (!ret && !(current->real_parent->flags & PF_EXITING)) { in ptrace_traceme()
521 current->ptrace = PT_PTRACED; in ptrace_traceme()
522 ptrace_link(current, current->real_parent); in ptrace_traceme()
536 spin_lock(&sigh->siglock); in ignoring_children()
537 ret = (sigh->action[SIGCHLD-1].sa.sa_handler == SIG_IGN) || in ignoring_children()
538 (sigh->action[SIGCHLD-1].sa.sa_flags & SA_NOCLDWAIT); in ignoring_children()
539 spin_unlock(&sigh->siglock); in ignoring_children()
550 * or self-reaping. Do notification now if it would have happened earlier.
554 * children self-reap, then this child was prevented by ptrace and we must
555 * reap it now, in that case we must also wake up sub-threads sleeping in
564 if (p->exit_state != EXIT_ZOMBIE) in __ptrace_detach()
570 if (!same_thread_group(p->real_parent, tracer)) in __ptrace_detach()
571 dead = do_notify_parent(p, p->exit_signal); in __ptrace_detach()
572 else if (ignoring_children(tracer->sighand)) { in __ptrace_detach()
579 p->exit_state = EXIT_DEAD; in __ptrace_detach()
586 return -EIO; in ptrace_detach()
588 /* Architecture-specific hardware disable .. */ in ptrace_detach()
596 WARN_ON(!child->ptrace || child->exit_state); in ptrace_detach()
601 child->exit_code = data; in ptrace_detach()
618 list_for_each_entry_safe(p, n, &tracer->ptraced, ptrace_entry) { in exit_ptrace()
619 if (unlikely(p->ptrace & PT_EXITKILL)) in exit_ptrace()
623 list_add(&p->ptrace_entry, dead); in exit_ptrace()
641 return -EIO; in ptrace_readdata()
644 return -EFAULT; in ptrace_readdata()
648 len -= retval; in ptrace_readdata()
663 return -EFAULT; in ptrace_writedata()
669 return -EIO; in ptrace_writedata()
674 len -= retval; in ptrace_writedata()
689 flags = child->ptrace; in ptrace_setoptions()
692 child->ptrace = flags; in ptrace_setoptions()
700 int error = -ESRCH; in ptrace_getsiginfo()
703 error = -EINVAL; in ptrace_getsiginfo()
704 if (likely(child->last_siginfo != NULL)) { in ptrace_getsiginfo()
705 copy_siginfo(info, child->last_siginfo); in ptrace_getsiginfo()
716 int error = -ESRCH; in ptrace_setsiginfo()
719 error = -EINVAL; in ptrace_setsiginfo()
720 if (likely(child->last_siginfo != NULL)) { in ptrace_setsiginfo()
721 copy_siginfo(child->last_siginfo, info); in ptrace_setsiginfo()
741 return -EFAULT; in ptrace_peek_siginfo()
744 return -EINVAL; /* unknown flags */ in ptrace_peek_siginfo()
747 return -EINVAL; in ptrace_peek_siginfo()
754 pending = &child->signal->shared_pending; in ptrace_peek_siginfo()
756 pending = &child->pending; in ptrace_peek_siginfo()
763 spin_lock_irq(&child->sighand->siglock); in ptrace_peek_siginfo()
764 list_for_each_entry(q, &pending->list, list) { in ptrace_peek_siginfo()
765 if (!off--) { in ptrace_peek_siginfo()
767 copy_siginfo(&info, &q->info); in ptrace_peek_siginfo()
771 spin_unlock_irq(&child->sighand->siglock); in ptrace_peek_siginfo()
781 ret = -EFAULT; in ptrace_peek_siginfo()
791 ret = -EFAULT; in ptrace_peek_siginfo()
816 .rseq_abi_pointer = (u64)(uintptr_t)task->rseq, in ptrace_get_rseq_configuration()
817 .rseq_abi_size = task->rseq_len, in ptrace_get_rseq_configuration()
818 .signature = task->rseq_sig, in ptrace_get_rseq_configuration()
824 return -EFAULT; in ptrace_get_rseq_configuration()
847 return -EIO; in ptrace_resume()
863 return -EIO; in ptrace_resume()
867 return -EIO; in ptrace_resume()
874 * Change ->exit_code and ->state under siglock to avoid the race in ptrace_resume()
875 * with wait_task_stopped() in between; a non-zero ->exit_code will in ptrace_resume()
878 * Note that we need siglock even if ->exit_code == data and/or this in ptrace_resume()
882 spin_lock_irq(&child->sighand->siglock); in ptrace_resume()
883 child->exit_code = data; in ptrace_resume()
884 child->jobctl &= ~JOBCTL_TRACED; in ptrace_resume()
886 spin_unlock_irq(&child->sighand->siglock); in ptrace_resume()
899 for (n = 0; n < view->n; ++n) { in find_regset()
900 regset = view->regsets + n; in find_regset()
901 if (regset->core_note_type == type) in find_regset()
915 if (!regset || (kiov->iov_len % regset->size) != 0) in ptrace_regset()
916 return -EINVAL; in ptrace_regset()
918 regset_no = regset - view->regsets; in ptrace_regset()
919 kiov->iov_len = min(kiov->iov_len, in ptrace_regset()
920 (__kernel_size_t) (regset->n * regset->size)); in ptrace_regset()
924 kiov->iov_len, kiov->iov_base); in ptrace_regset()
927 kiov->iov_len, kiov->iov_base); in ptrace_regset()
931 * This is declared in linux/regset.h and defined in machine-dependent
932 * code. We put the export here, near the primary machine-neutral use,
941 unsigned long args[ARRAY_SIZE(info->entry.args)]; in ptrace_get_syscall_info_entry()
944 info->op = PTRACE_SYSCALL_INFO_ENTRY; in ptrace_get_syscall_info_entry()
945 info->entry.nr = syscall_get_nr(child, regs); in ptrace_get_syscall_info_entry()
948 info->entry.args[i] = args[i]; in ptrace_get_syscall_info_entry()
960 * of struct ptrace_syscall_info.seccomp, it makes sense to in ptrace_get_syscall_info_seccomp()
966 info->op = PTRACE_SYSCALL_INFO_SECCOMP; in ptrace_get_syscall_info_seccomp()
967 info->seccomp.ret_data = child->ptrace_message; in ptrace_get_syscall_info_seccomp()
969 /* ret_data is the last field in struct ptrace_syscall_info.seccomp */ in ptrace_get_syscall_info_seccomp()
970 return offsetofend(struct ptrace_syscall_info, seccomp.ret_data); in ptrace_get_syscall_info_seccomp()
977 info->op = PTRACE_SYSCALL_INFO_EXIT; in ptrace_get_syscall_info_exit()
978 info->exit.rval = syscall_get_error(child, regs); in ptrace_get_syscall_info_exit()
979 info->exit.is_error = !!info->exit.rval; in ptrace_get_syscall_info_exit()
980 if (!info->exit.is_error) in ptrace_get_syscall_info_exit()
981 info->exit.rval = syscall_get_return_value(child, regs); in ptrace_get_syscall_info_exit()
1003 * child->last_siginfo because ptrace_freeze_traced() in ptrace_get_syscall_info()
1007 switch (child->last_siginfo ? child->last_siginfo->si_code : 0) { in ptrace_get_syscall_info()
1009 switch (child->ptrace_message) { in ptrace_get_syscall_info()
1027 return copy_to_user(datavp, &info, write_size) ? -EFAULT : actual_size; in ptrace_get_syscall_info()
1034 bool seized = child->ptrace & PT_SEIZED; in ptrace_request()
1035 int ret = -EIO; in ptrace_request()
1056 ret = put_user(child->ptrace_message, datalp); in ptrace_request()
1079 ret = -EINVAL; in ptrace_request()
1084 mask = &child->saved_sigmask; in ptrace_request()
1086 mask = &child->blocked; in ptrace_request()
1089 ret = -EFAULT; in ptrace_request()
1100 ret = -EINVAL; in ptrace_request()
1105 ret = -EFAULT; in ptrace_request()
1116 spin_lock_irq(&child->sighand->siglock); in ptrace_request()
1117 child->blocked = new_set; in ptrace_request()
1118 spin_unlock_irq(&child->sighand->siglock); in ptrace_request()
1128 * Stop tracee without any side-effect on signal or job in ptrace_request()
1143 * STOP, this INTERRUPT should clear LISTEN and re-trap in ptrace_request()
1147 ptrace_signal_wake_up(child, child->jobctl & JOBCTL_LISTENING); in ptrace_request()
1156 * resumed per-se but is not considered to be in TRACED by in ptrace_request()
1160 * finish listening and re-trap tracee into STOP. in ptrace_request()
1165 si = child->last_siginfo; in ptrace_request()
1166 if (likely(si && (si->si_code >> 8) == PTRACE_EVENT_STOP)) { in ptrace_request()
1167 child->jobctl |= JOBCTL_LISTENING; in ptrace_request()
1170 * start of this trap and now. Trigger re-trap. in ptrace_request()
1172 if (child->jobctl & JOBCTL_TRAP_NOTIFY) in ptrace_request()
1188 ret = -ESRCH; in ptrace_request()
1194 tmp = mm->context.exec_fdpic_loadmap; in ptrace_request()
1197 tmp = mm->context.interp_fdpic_loadmap; in ptrace_request()
1232 return -EFAULT; in ptrace_request()
1234 if (__get_user(kiov.iov_base, &uiov->iov_base) || in ptrace_request()
1235 __get_user(kiov.iov_len, &uiov->iov_len)) in ptrace_request()
1236 return -EFAULT; in ptrace_request()
1240 ret = __put_user(kiov.iov_len, &uiov->iov_len); in ptrace_request()
1291 ret = -ESRCH; in SYSCALL_DEFINE4()
1323 return -EIO; in generic_ptrace_peekdata()
1334 return (copied == sizeof(data)) ? 0 : -EIO; in generic_ptrace_pokedata()
1353 ret = -EIO; in compat_ptrace_request()
1362 ret = (ret != sizeof(data) ? -EIO : 0); in compat_ptrace_request()
1366 ret = put_user((compat_ulong_t) child->ptrace_message, datap); in compat_ptrace_request()
1394 return -EFAULT; in compat_ptrace_request()
1396 if (__get_user(ptr, &uiov->iov_base) || in compat_ptrace_request()
1397 __get_user(len, &uiov->iov_len)) in compat_ptrace_request()
1398 return -EFAULT; in compat_ptrace_request()
1405 ret = __put_user(kiov.iov_len, &uiov->iov_len); in compat_ptrace_request()
1430 ret = -ESRCH; in COMPAT_SYSCALL_DEFINE4()