-/*
- * Routine: task_name_for_pid
- * Purpose:
- * Get the task name 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.
- *
- * XXX This should be a BSD system call, not a Mach trap!!!
- */
-
-kern_return_t
-task_name_for_pid(
- struct task_name_for_pid_args *args)
-{
- mach_port_name_t target_tport = args->target_tport;
- int pid = args->pid;
- user_addr_t task_addr = args->t;
- struct uthread *uthread;
- struct proc *p;
- struct proc *p1;
- task_t t1;
- mach_port_name_t tret;
- void * sright;
- int error = 0;
- boolean_t funnel_state;
-
- AUDIT_MACH_SYSCALL_ENTER(AUE_TASKNAMEFORPID);
- AUDIT_ARG(pid, pid);
- AUDIT_ARG(mach_port1, target_tport);
-
- t1 = port_name_to_task(target_tport);
- if (t1 == TASK_NULL) {
- (void ) copyout((char *)&t1, task_addr, sizeof(mach_port_name_t));
- AUDIT_MACH_SYSCALL_EXIT(KERN_FAILURE);
- return(KERN_FAILURE);
- }
-
- funnel_state = thread_funnel_set(kernel_flock, TRUE);
-
- p1 = current_proc();
-
- /*
- * Delayed binding of thread credential to process credential, if we
- * are not running with an explicitly set thread credential.
- */
- /*
- * XXX p_ucred check can be bogus in multithreaded processes,
- * XXX unless the funnel is held.
- */
- uthread = get_bsdthread_info(current_thread());
- if (uthread->uu_ucred != p1->p_ucred &&
- (uthread->uu_flag & UT_SETUID) == 0) {
- kauth_cred_t old = uthread->uu_ucred;
- proc_lock(p1);
- kauth_cred_ref(p1->p_ucred);
- uthread->uu_ucred = p1->p_ucred;
- proc_unlock(p1);
- if (IS_VALID_CRED(old))
- kauth_cred_unref(&old);
- }
-
- p = pfind(pid);
- AUDIT_ARG(process, p);
-
- if ((p != (struct proc *) 0)
- && (p->p_stat != SZOMB)
- && (p1 != (struct proc *) 0)
- && ((p1 == p)
- || !(suser(kauth_cred_get(), 0))
- || ((kauth_cred_getuid(p->p_ucred) == kauth_cred_getuid(kauth_cred_get())) &&
- ((p->p_ucred->cr_ruid == kauth_cred_get()->cr_ruid)))))
- {
- if (p->task != TASK_NULL)
- {
- task_reference(p->task);
- sright = (void *)convert_task_name_to_port(p->task);
- tret = ipc_port_copyout_send(
- sright,
- get_task_ipcspace(current_task()));
- } else
- tret = MACH_PORT_NULL;
- AUDIT_ARG(mach_port2, tret);
- (void ) copyout((char *)&tret, task_addr, sizeof(mach_port_name_t));
- task_deallocate(t1);
- error = KERN_SUCCESS;
- goto tnfpout;
- }
-
- task_deallocate(t1);
- tret = MACH_PORT_NULL;
- (void) copyout((char *) &tret, task_addr, sizeof(mach_port_name_t));
- error = KERN_FAILURE;
-tnfpout:
- thread_funnel_set(kernel_flock, funnel_state);
- AUDIT_MACH_SYSCALL_EXIT(error);
- return(error);
-}
-
-static int
-sysctl_settfp_policy(__unused struct sysctl_oid *oidp, void *arg1,
- __unused int arg2, struct sysctl_req *req)
-{
- int error = 0;
- int new_value;
-
- error = SYSCTL_OUT(req, arg1, sizeof(int));
- if (error || req->newptr == USER_ADDR_NULL)
- return(error);
-
- if (!is_suser())
- return(EPERM);
-
- if ((error = SYSCTL_IN(req, &new_value, sizeof(int)))) {
- goto out;
- }
- if ((new_value == KERN_TFP_POLICY_DENY)
- || (new_value == KERN_TFP_POLICY_PERMISSIVE)
- || (new_value == KERN_TFP_POLICY_RESTRICTED))
- tfp_policy = new_value;
- else
- error = EINVAL;
-out:
- return(error);
-
-}
-
-static int
-sysctl_settfp_groups(__unused struct sysctl_oid *oidp, void *arg1,
- __unused int arg2, struct sysctl_req *req)
-{
- int error = 0;
- int new_value;
-
- error = SYSCTL_OUT(req, arg1, sizeof(int));
- if (error || req->newptr == USER_ADDR_NULL)
- return(error);
-
- if (!is_suser())
- return(EPERM);
-
- /*
- * Once set; cannot be reset till next boot. Launchd will set this
- * in its pid 1 init and no one can set after that.
- */
- if (tfp_group_inited != 0)
- return(EPERM);
-
- if ((error = SYSCTL_IN(req, &new_value, sizeof(int)))) {
- goto out;
- }
-
- if (new_value >= 100)
- error = EINVAL;
- else {
- if (arg1 == &tfp_group_ronly)
- tfp_group_ronly = new_value;
- else if (arg1 == &tfp_group_rw)
- tfp_group_rw = new_value;
- else
- error = EINVAL;
- if ((tfp_group_ronly != 0 ) && (tfp_group_rw != 0 ))
- tfp_group_inited = 1;
- }
-
-out:
- return(error);
-}
-
-SYSCTL_NODE(_kern, KERN_TFP, tfp, CTLFLAG_RW, 0, "tfp");
-SYSCTL_PROC(_kern_tfp, KERN_TFP_POLICY, policy, CTLTYPE_INT | CTLFLAG_RW,
- &tfp_policy, sizeof(uint32_t), &sysctl_settfp_policy ,"I","policy");
-SYSCTL_PROC(_kern_tfp, KERN_TFP_READ_GROUP, read_group, CTLTYPE_INT | CTLFLAG_RW,
- &tfp_group_ronly, sizeof(uint32_t), &sysctl_settfp_groups ,"I","read_group");
-SYSCTL_PROC(_kern_tfp, KERN_TFP_RW_GROUP, rw_group, CTLTYPE_INT | CTLFLAG_RW,
- &tfp_group_rw, sizeof(uint32_t), &sysctl_settfp_groups ,"I","rw_group");
-
-
-SYSCTL_INT(_vm, OID_AUTO, shared_region_trace_level, CTLFLAG_RW, &shared_region_trace_level, 0, "");