Task-port access and authorization
task_for_pid checks process credentials and task-port policy, applies MAC checks when configured, and may wait for an authorization reply from the task access server. The POSIX check alone does not determine whether a debugger receives a control port.
task_for_pid_posix_check source
Routine: task_for_pid_posix_check
Purpose:
Verify that the current process should be allowed to
get the target process's task port. This is only
permitted if:
- The current process is root
OR all of the following are true:
- The target process's real, effective, and saved uids
are the same as the current proc's euid,
- The target process's group set is a subset of the
calling process's group set, and
- The target process hasn't switched credentials.
Returns: TRUE: permitted
FALSE: denied
static int task_for_pid_posix_check(proc_t target) { kauth_cred_t targetcred, mycred; bool checkcredentials; uid_t myuid; int allowed; /* No task_for_pid on bad targets */ if (target->p_stat == SZOMB) { return FALSE; } mycred = kauth_cred_get(); myuid = kauth_cred_getuid(mycred); /* If we're running as root, the check passes */ if (kauth_cred_issuser(mycred)) { return TRUE; } /* We're allowed to get our own task port */ if (target == current_proc()) { return TRUE; } /* * Under DENY, only root can get another proc's task port, * so no more checks are needed. */ … more in source
task_for_pid source · task_for_pid reference
Routine: task_for_pid
Purpose:
Get the task port for another "process", named by its
process ID on the same host as "target_task".
Only permitted to privileged processes, or processes
with the same user ID.
Note: if pid == 0, an error is return no matter who is calling.
XXX This should be a BSD system call, not a Mach trap!!!
kern_return_t task_for_pid( struct task_for_pid_args *args) { mach_port_name_t target_tport = args->target_tport; int pid = args->pid; user_addr_t task_addr = args->t; proc_t p = PROC_NULL; task_t t1 = TASK_NULL; task_t task = TASK_NULL; mach_port_name_t tret = MACH_PORT_NULL; ipc_port_t tfpport = MACH_PORT_NULL; void * sright = NULL; int error = 0; boolean_t is_current_proc = FALSE; struct proc_ident pident = {0}; AUDIT_MACH_SYSCALL_ENTER(AUE_TASKFORPID); AUDIT_ARG(pid, pid); AUDIT_ARG(mach_port1, target_tport); /* Always check if pid == 0 */ if (pid == 0) { (void) copyout((char *)&tret, task_addr, sizeof(mach_port_name_t)); AUDIT_MACH_SYSCALL_EXIT(KERN_FAILURE); return KERN_FAILURE; } t1 = port_name_to_task(target_tport); if (t1 == TASK_NULL) { … more in source