static struct proc * mac_task_get_proc(struct task *task) { if (task == current_task()) return proc_self(); /* * Tasks don't really hold a reference on a proc unless the * calling thread belongs to the task in question. */ int pid = task_pid(task); struct proc *p = proc_find(pid); if (p != NULL) { if (proc_task(p) == task) return p; proc_rele(p); } return NULL; }
/* system call implementation */ int process_policy(__unused struct proc *p, struct process_policy_args * uap, __unused int32_t *retval) { int error = 0; int scope = uap->scope; int policy = uap->policy; int action = uap->action; int policy_subtype = uap->policy_subtype; user_addr_t attrp = uap->attrp; pid_t target_pid = uap->target_pid; uint64_t target_threadid = uap->target_threadid; proc_t target_proc = PROC_NULL; #if CONFIG_MACF || !CONFIG_EMBEDDED proc_t curp = current_proc(); #endif kauth_cred_t my_cred; #if CONFIG_EMBEDDED kauth_cred_t target_cred; #endif if ((scope != PROC_POLICY_SCOPE_PROCESS) && (scope != PROC_POLICY_SCOPE_THREAD)) { return(EINVAL); } if (target_pid == 0 || target_pid == proc_selfpid()) target_proc = proc_self(); else target_proc = proc_find(target_pid); if (target_proc == PROC_NULL) return(ESRCH); my_cred = kauth_cred_get(); #if CONFIG_EMBEDDED target_cred = kauth_cred_proc_ref(target_proc); if (!kauth_cred_issuser(my_cred) && kauth_cred_getruid(my_cred) && kauth_cred_getuid(my_cred) != kauth_cred_getuid(target_cred) && kauth_cred_getruid(my_cred) != kauth_cred_getuid(target_cred)) #else /* * Resoure starvation control can be used by unpriv resource owner but priv at the time of ownership claim. This is * checked in low resource handle routine. So bypass the checks here. */ if ((policy != PROC_POLICY_RESOURCE_STARVATION) && (policy != PROC_POLICY_APPTYPE) && (!kauth_cred_issuser(my_cred) && curp != p)) #endif { error = EPERM; goto out; } #if CONFIG_MACF switch (policy) { case PROC_POLICY_BOOST: case PROC_POLICY_RESOURCE_USAGE: #if CONFIG_EMBEDDED case PROC_POLICY_APPTYPE: case PROC_POLICY_APP_LIFECYCLE: #endif /* These policies do their own appropriate mac checks */ break; default: error = mac_proc_check_sched(curp, target_proc); if (error) goto out; break; } #endif /* CONFIG_MACF */ switch(policy) { case PROC_POLICY_BACKGROUND: error = ENOTSUP; break; case PROC_POLICY_HARDWARE_ACCESS: error = ENOTSUP; break; case PROC_POLICY_RESOURCE_STARVATION: error = handle_lowresource(scope, action, policy, policy_subtype, attrp, target_proc, target_threadid); break; case PROC_POLICY_RESOURCE_USAGE: switch(policy_subtype) { case PROC_POLICY_RUSAGE_NONE: case PROC_POLICY_RUSAGE_WIREDMEM: case PROC_POLICY_RUSAGE_VIRTMEM: case PROC_POLICY_RUSAGE_DISK: case PROC_POLICY_RUSAGE_NETWORK: case PROC_POLICY_RUSAGE_POWER: error = ENOTSUP; goto out; default: error = EINVAL; goto out; case PROC_POLICY_RUSAGE_CPU: break; } error = handle_cpuuse(action, attrp, target_proc, target_threadid); break; #if CONFIG_EMBEDDED case PROC_POLICY_APP_LIFECYCLE: error = handle_applifecycle(scope, action, policy, policy_subtype, attrp, target_proc, target_threadid); break; #endif /* CONFIG_EMBEDDED */ case PROC_POLICY_APPTYPE: error = handle_apptype(scope, action, policy, policy_subtype, attrp, target_proc, target_threadid); break; case PROC_POLICY_BOOST: error = handle_boost(scope, action, policy, policy_subtype, attrp, target_proc, target_threadid); break; default: error = EINVAL; break; } out: proc_rele(target_proc); #if CONFIG_EMBEDDED kauth_cred_unref(&target_cred); #endif return(error); }