X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/fe8ab488e9161c46dd9885d58fc52996dc0249ff..008676633c2ad2c325837c2b64915f7ded690a8f:/bsd/kern/kern_resource.c diff --git a/bsd/kern/kern_resource.c b/bsd/kern/kern_resource.c index 2900cd52b..625916715 100644 --- a/bsd/kern/kern_resource.c +++ b/bsd/kern/kern_resource.c @@ -98,6 +98,7 @@ #include #include /* for thread_policy_set( ) */ #include +#include #include #include /* for absolutetime_to_microtime() */ @@ -108,19 +109,19 @@ #include #include +#include +#include int donice(struct proc *curp, struct proc *chgp, int n); int dosetrlimit(struct proc *p, u_int which, struct rlimit *limp); int uthread_get_background_state(uthread_t); static void do_background_socket(struct proc *p, thread_t thread); -static int do_background_thread(struct proc *curp, thread_t thread, int priority); +static int do_background_thread(thread_t thread, int priority); static int do_background_proc(struct proc *curp, struct proc *targetp, int priority); static int set_gpudeny_proc(struct proc *curp, struct proc *targetp, int priority); static int proc_set_darwin_role(proc_t curp, proc_t targetp, int priority); static int proc_get_darwin_role(proc_t curp, proc_t targetp, int *priority); static int get_background_proc(struct proc *curp, struct proc *targetp, int *priority); -void proc_apply_task_networkbg_internal(proc_t, thread_t); -void proc_restore_task_networkbg_internal(proc_t, thread_t); int proc_pid_rusage(int pid, int flavor, user_addr_t buf, int32_t *retval); void gather_rusage_info(proc_t p, rusage_info_current *ru, int flavor); int fill_task_rusage(task_t task, rusage_info_current *ri); @@ -211,7 +212,7 @@ getpriority(struct proc *curp, struct getpriority_args *uap, int32_t *retval) } /* No need for iteration as it is a simple scan */ pgrp_lock(pg); - for (p = pg->pg_members.lh_first; p != 0; p = p->p_pglist.le_next) { + PGMEMBERS_FOREACH(pg, p) { if (p->p_nice < low) low = p->p_nice; } @@ -243,7 +244,7 @@ getpriority(struct proc *curp, struct getpriority_args *uap, int32_t *retval) if (uap->who != 0) return (EINVAL); - low = proc_get_task_policy(current_task(), current_thread(), TASK_POLICY_INTERNAL, TASK_POLICY_DARWIN_BG); + low = proc_get_thread_policy(current_thread(), TASK_POLICY_INTERNAL, TASK_POLICY_DARWIN_BG); break; @@ -416,7 +417,7 @@ setpriority(struct proc *curp, struct setpriority_args *uap, int32_t *retval) if (uap->who != 0) return (EINVAL); - error = do_background_thread(curp, current_thread(), uap->prio); + error = do_background_thread(current_thread(), uap->prio); found++; break; } @@ -592,8 +593,10 @@ proc_set_darwin_role(proc_t curp, proc_t targetp, int priority) if (!kauth_cred_issuser(ucred) && kauth_cred_getruid(ucred) && kauth_cred_getuid(ucred) != kauth_cred_getuid(target_cred) && kauth_cred_getruid(ucred) != kauth_cred_getuid(target_cred)) { - error = EPERM; - goto out; + if (priv_check_cred(ucred, PRIV_SETPRIORITY_DARWIN_ROLE, 0) != 0) { + error = EPERM; + goto out; + } } if (curp != targetp) { @@ -611,26 +614,11 @@ proc_set_darwin_role(proc_t curp, proc_t targetp, int priority) integer_t role = 0; - switch (priority) { - case PRIO_DARWIN_ROLE_DEFAULT: - role = TASK_UNSPECIFIED; - break; - case PRIO_DARWIN_ROLE_UI_FOCAL: - role = TASK_FOREGROUND_APPLICATION; - break; - case PRIO_DARWIN_ROLE_UI: - role = TASK_BACKGROUND_APPLICATION; - break; - case PRIO_DARWIN_ROLE_NON_UI: - role = TASK_NONUI_APPLICATION; - break; - default: - error = EINVAL; - goto out; - } + if ((error = proc_darwin_role_to_task_role(priority, &role))) + goto out; - proc_set_task_policy(proc_task(targetp), THREAD_NULL, - TASK_POLICY_ATTRIBUTE, TASK_POLICY_ROLE, role); + proc_set_task_policy(proc_task(targetp), TASK_POLICY_ATTRIBUTE, + TASK_POLICY_ROLE, role); out: kauth_cred_unref(&target_cred); @@ -662,24 +650,9 @@ proc_get_darwin_role(proc_t curp, proc_t targetp, int *priority) #endif } - role = proc_get_task_policy(proc_task(targetp), THREAD_NULL, - TASK_POLICY_ATTRIBUTE, TASK_POLICY_ROLE); + role = proc_get_task_policy(proc_task(targetp), TASK_POLICY_ATTRIBUTE, TASK_POLICY_ROLE); - switch (role) { - case TASK_FOREGROUND_APPLICATION: - *priority = PRIO_DARWIN_ROLE_UI_FOCAL; - break; - case TASK_BACKGROUND_APPLICATION: - *priority = PRIO_DARWIN_ROLE_UI; - break; - case TASK_NONUI_APPLICATION: - *priority = PRIO_DARWIN_ROLE_NON_UI; - break; - case TASK_UNSPECIFIED: - default: - *priority = PRIO_DARWIN_ROLE_DEFAULT; - break; - } + *priority = proc_task_role_to_darwin_role(role); out: kauth_cred_unref(&target_cred); @@ -706,7 +679,7 @@ get_background_proc(struct proc *curp, struct proc *targetp, int *priority) external = (curp == targetp) ? TASK_POLICY_INTERNAL : TASK_POLICY_EXTERNAL; - *priority = proc_get_task_policy(current_task(), THREAD_NULL, external, TASK_POLICY_DARWIN_BG); + *priority = proc_get_task_policy(current_task(), external, TASK_POLICY_DARWIN_BG); out: kauth_cred_unref(&target_cred); @@ -757,7 +730,7 @@ do_background_proc(struct proc *curp, struct proc *targetp, int priority) break; } - proc_set_task_policy(proc_task(targetp), THREAD_NULL, external, TASK_POLICY_DARWIN_BG, enable); + proc_set_task_policy(proc_task(targetp), external, TASK_POLICY_DARWIN_BG, enable); out: kauth_cred_unref(&target_cred); @@ -835,12 +808,15 @@ do_background_socket(struct proc *p, thread_t thread) /* * do_background_thread + * + * Requires: thread reference + * * Returns: 0 Success * EPERM Tried to background while in vfork * XXX - todo - does this need a MACF hook? */ static int -do_background_thread(struct proc *curp, thread_t thread, int priority) +do_background_thread(thread_t thread, int priority) { struct uthread *ut; int enable, external; @@ -852,6 +828,7 @@ do_background_thread(struct proc *curp, thread_t thread, int priority) if ((ut->uu_flag & UT_VFORK) != 0) return(EPERM); + /* Backgrounding is unsupported for workq threads */ if (thread_is_static_param(thread)) { return(EPERM); } @@ -866,8 +843,7 @@ do_background_thread(struct proc *curp, thread_t thread, int priority) enable = (priority == PRIO_DARWIN_BG) ? TASK_POLICY_ENABLE : TASK_POLICY_DISABLE; external = (current_thread() == thread) ? TASK_POLICY_INTERNAL : TASK_POLICY_EXTERNAL; - proc_set_task_policy_thread(curp->task, thread_tid(thread), external, - TASK_POLICY_DARWIN_BG, enable); + proc_set_thread_policy(thread, external, TASK_POLICY_DARWIN_BG, enable); return rv; } @@ -1580,14 +1556,16 @@ iopolicysys_disk(struct proc *p __unused, int cmd, int scope, int policy, struct /* Perform command */ switch(cmd) { case IOPOL_CMD_SET: - proc_set_task_policy(current_task(), thread, - TASK_POLICY_INTERNAL, policy_flavor, - policy); + if (thread != THREAD_NULL) + proc_set_thread_policy(thread, TASK_POLICY_INTERNAL, policy_flavor, policy); + else + proc_set_task_policy(current_task(), TASK_POLICY_INTERNAL, policy_flavor, policy); break; case IOPOL_CMD_GET: - policy = proc_get_task_policy(current_task(), thread, - TASK_POLICY_INTERNAL, policy_flavor); - + if (thread != THREAD_NULL) + policy = proc_get_thread_policy(thread, TASK_POLICY_INTERNAL, policy_flavor); + else + policy = proc_get_task_policy(current_task(), TASK_POLICY_INTERNAL, policy_flavor); iop_param->iop_policy = policy; break; default: @@ -1632,8 +1610,13 @@ iopolicysys_vfs(struct proc *p, int cmd, int scope, int policy, struct _iopol_pa switch(cmd) { case IOPOL_CMD_SET: if (0 == kauth_cred_issuser(kauth_cred_get())) { - error = EPERM; - goto out; + /* If it's a non-root process, it needs to have the entitlement to set the policy */ + boolean_t entitled = FALSE; + entitled = IOTaskHasEntitlement(current_task(), "com.apple.private.iopol.case_sensitivity"); + if (!entitled) { + error = EPERM; + goto out; + } } switch (policy) { @@ -1663,9 +1646,7 @@ out: return (error); } -/* BSD call back function for task_policy */ -void proc_apply_task_networkbg(void * bsd_info, thread_t thread); - +/* BSD call back function for task_policy networking changes */ void proc_apply_task_networkbg(void * bsd_info, thread_t thread) {