#include <pexpert/pexpert.h>
+#if CONFIG_MACF
+#include <security/mac_framework.h>
+#endif
+
/* XXX ken/bsd_kern.c - prototype should be in common header */
int get_task_userstop(task_t);
AUDIT_ARG(value32, uap->data);
if (uap->req == PT_DENY_ATTACH) {
+#if (DEVELOPMENT || DEBUG) && CONFIG_EMBEDDED
+ if (PE_i_can_has_debugger(NULL))
+ return(0);
+#endif
proc_lock(p);
if (ISSET(p->p_lflag, P_LTRACED)) {
proc_unlock(p);
KERNEL_DEBUG_CONSTANT(BSDDBG_CODE(DBG_BSD_PROC, BSD_PROC_FRCEXIT) | DBG_FUNC_NONE,
p->p_pid, W_EXITCODE(ENOTSUP, 0), 4, 0, 0);
exit1(p, W_EXITCODE(ENOTSUP, 0), retval);
- /* drop funnel before we return */
+
thread_exception_return();
/* NOTREACHED */
}
* Intercept and deal with "please trace me" request.
*/
if (uap->req == PT_TRACE_ME) {
- proc_lock(p);
- SET(p->p_lflag, P_LTRACED);
- /* Non-attached case, our tracer is our parent. */
- p->p_oppid = p->p_ppid;
- /* Check whether child and parent are allowed to run modified
- * code (they'll have to) */
- struct proc *pproc=proc_find(p->p_oppid);
- proc_unlock(p);
- cs_allow_invalid(p);
- if(pproc) {
+retry_trace_me:;
+ proc_t pproc = proc_parent(p);
+ if (pproc == NULL)
+ return (EINVAL);
+#if CONFIG_MACF
+ /*
+ * NB: Cannot call kauth_authorize_process(..., KAUTH_PROCESS_CANTRACE, ...)
+ * since that assumes the process being checked is the current process
+ * when, in this case, it is the current process's parent.
+ * Most of the other checks in cantrace() don't apply either.
+ */
+ if ((error = mac_proc_check_debug(pproc, p)) == 0) {
+#endif
+ proc_lock(p);
+ /* Make sure the process wasn't re-parented. */
+ if (p->p_ppid != pproc->p_pid) {
+ proc_unlock(p);
+ proc_rele(pproc);
+ goto retry_trace_me;
+ }
+ SET(p->p_lflag, P_LTRACED);
+ /* Non-attached case, our tracer is our parent. */
+ p->p_oppid = p->p_ppid;
+ proc_unlock(p);
+ /* Child and parent will have to be able to run modified code. */
+ cs_allow_invalid(p);
cs_allow_invalid(pproc);
- proc_rele(pproc);
+#if CONFIG_MACF
}
- return(0);
+#endif
+ proc_rele(pproc);
+ return (error);
}
if (uap->req == PT_SIGEXC) {
proc_lock(p);
task = t->task;
if (uap->req == PT_ATTACHEXC) {
+#pragma clang diagnostic push
+#pragma clang diagnostic ignored "-Wdeprecated-declarations"
uap->req = PT_ATTACH;
tr_sigexc = 1;
}
if (uap->req == PT_ATTACH) {
+#pragma clang diagnostic pop
int err;
-
+
+#if CONFIG_EMBEDDED
+ if (tr_sigexc == 0) {
+ error = ENOTSUP;
+ goto out;
+ }
+#endif
+
if ( kauth_authorize_process(proc_ucred(p), KAUTH_PROCESS_CANTRACE,
t, (uintptr_t)&err, 0, 0) == 0 ) {
/* it's OK to attach */
}
if (uap->data != 0) {
+#if CONFIG_MACF
+ error = mac_proc_check_signal(p, t, uap->data);
+ if (0 != error)
+ goto out;
+#endif
psignal(t, uap->data);
- }
+ }
if (uap->req == PT_STEP) {
/*
goto out;
}
th_act = port_name_to_thread(CAST_MACH_PORT_TO_NAME(uap->addr));
- if (th_act == THREAD_NULL)
- return (ESRCH);
+ if (th_act == THREAD_NULL) {
+ error = ESRCH;
+ goto out;
+ }
ut = (uthread_t)get_bsdthread_info(th_act);
if (uap->data)
ut->uu_siglist |= sigmask(uap->data);
*errp = EBUSY;
return (0);
}
+
+#if CONFIG_MACF
+ if ((my_err = mac_proc_check_debug(cur_procp, traced_procp)) != 0) {
+ *errp = my_err;
+ return (0);
+ }
+#endif
+
return(1);
}