]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/kern/kern_resource.c
xnu-3789.60.24.tar.gz
[apple/xnu.git] / bsd / kern / kern_resource.c
index 2900cd52bac3ea357a9242f54c27eff5e24c9b5c..6259167150b53f6f8b7cf84c04568c0423456093 100644 (file)
@@ -98,6 +98,7 @@
 #include <mach/mach_vm.h>
 #include <mach/thread_act.h>  /* for thread_policy_set( ) */
 #include <kern/thread.h>
+#include <kern/policy_internal.h>
 
 #include <kern/task.h>
 #include <kern/clock.h>                /* for absolutetime_to_microtime() */
 
 #include <kern/assert.h>
 #include <sys/resource.h>
+#include <sys/priv.h>
+#include <IOKit/IOBSD.h>
 
 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)
 {