]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/kern/process_policy.c
xnu-2782.30.5.tar.gz
[apple/xnu.git] / bsd / kern / process_policy.c
index ff919538fb4c1918dfff316766606b5a36ab2c66..ded6d7215515cfb30c32859768fbe365b271e9ef 100644 (file)
@@ -35,6 +35,7 @@
 #include <sys/kernel.h>
 #include <sys/malloc.h>
 #include <sys/proc_internal.h>
+#include <sys/proc.h>
 #include <sys/kauth.h>
 #include <sys/unistd.h>
 #include <sys/buf.h>
@@ -48,7 +49,6 @@
 #include <mach/mach_types.h>
 #include <mach/vm_param.h>
 #include <kern/task.h>
-#include <kern/lock.h>
 #include <kern/kalloc.h>
 #include <kern/assert.h>
 #include <vm/vm_kern.h>
 
 #include <kern/ipc_misc.h>
 #include <vm/vm_protos.h>
-#if CONFIG_EMBEDDED
-#include <security/mac.h>
-#include <sys/kern_memorystatus.h>
-#endif /* CONFIG_EMBEDDED */
-
-static int handle_background(int scope, int action, int policy, int policy_subtype, user_addr_t attrp, proc_t proc, uint64_t target_threadid);
-static int handle_hwaccess(int scope, int action, int policy, int policy_subtype, user_addr_t attrp, proc_t proc, uint64_t target_threadid);
-static int handle_lowresrouce(int scope, int action, int policy, int policy_subtype, user_addr_t attrp, proc_t proc, uint64_t target_threadid);
+
+static int handle_lowresource(int scope, int action, int policy, int policy_subtype, user_addr_t attrp, proc_t proc, uint64_t target_threadid);
 static int handle_resourceuse(int scope, int action, int policy, int policy_subtype, user_addr_t attrp, proc_t proc, uint64_t target_threadid);
 static int handle_apptype(int scope, int action, int policy, int policy_subtype, user_addr_t attrp, proc_t proc, uint64_t target_threadid);
+static int handle_boost(int scope, int action, int policy, int policy_subtype, user_addr_t attrp, proc_t proc, uint64_t target_threadid);
 
 extern kern_return_t task_suspend(task_t);
 extern kern_return_t task_resume(task_t);
 
-#if CONFIG_EMBEDDED
-static int handle_applifecycle(int scope, int action, int policy, int policy_subtype, user_addr_t attrp, proc_t proc, uint64_t target_threadid);
-#endif /* CONFIG_EMBEDDED */
-
 
 /***************************** process_policy ********************/
 
@@ -98,7 +89,7 @@ static int handle_applifecycle(int scope, int action, int policy, int policy_sub
  * user_addr_t attrp, pid_t target_pid, uint64_t target_threadid); }
  */
 
-/* system call implementaion */
+/* system call implementation */
 int
 process_policy(__unused struct proc *p, struct process_policy_args * uap, __unused int32_t *retval)
 {
@@ -113,27 +104,21 @@ process_policy(__unused struct proc *p, struct process_policy_args * uap, __unus
        proc_t target_proc = PROC_NULL;
        proc_t curp = current_proc();
        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);
        }
-       target_proc = proc_find(target_pid);
-       if (target_proc == PROC_NULL)  {
+
+       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.
@@ -141,47 +126,43 @@ process_policy(__unused struct proc *p, struct process_policy_args * uap, __unus
        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
-#if CONFIG_EMBEDDED
-       /* Lifecycle management will invoke approp macf checks */
-       if (policy != PROC_POLICY_APP_LIFECYCLE) {
-#endif /* CONFIG_EMBEDDED */
-               error = mac_proc_check_sched(curp, target_proc);
-               if (error) 
-                       goto out;
-#if CONFIG_EMBEDDED
+       switch (policy) {
+               case PROC_POLICY_BOOST:
+               case PROC_POLICY_RESOURCE_USAGE:
+                       /* 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_EMBEDDED */
 #endif /* CONFIG_MACF */
 
-
        switch(policy) {
                case PROC_POLICY_BACKGROUND:
-                       error = handle_background(scope, action, policy, policy_subtype, attrp, target_proc, target_threadid);
+                       error = ENOTSUP;
                        break;
                case PROC_POLICY_HARDWARE_ACCESS:
-                       error = handle_hwaccess(scope, action, policy, policy_subtype, attrp, target_proc, target_threadid);
+                       error = ENOTSUP;
                        break;
                case PROC_POLICY_RESOURCE_STARVATION:
-                       error = handle_lowresrouce(scope, action, policy, policy_subtype, attrp, target_proc, target_threadid);
+                       error = handle_lowresource(scope, action, policy, policy_subtype, attrp, target_proc, target_threadid);
                        break;
                case PROC_POLICY_RESOURCE_USAGE:
                        error = handle_resourceuse(scope, action, policy, policy_subtype, 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;
@@ -189,131 +170,11 @@ process_policy(__unused struct proc *p, struct process_policy_args * uap, __unus
 
 out:
        proc_rele(target_proc);
-#if CONFIG_EMBEDDED
-        kauth_cred_unref(&target_cred);
-#endif
        return(error);
 }
 
-
-/* darwin background handling code */
-static int 
-handle_background(int scope, int action, __unused int policy, __unused int policy_subtype, user_addr_t attrp, proc_t proc, uint64_t target_threadid)
-{
-       int intval, error = 0;
-
-
-       switch (action) {
-               case PROC_POLICY_ACTION_GET: 
-                       if (scope == PROC_POLICY_SCOPE_PROCESS) {
-                               intval = proc_get_task_bg_policy(proc->task);
-                       } else {
-                               /* thread scope */
-                               intval = proc_get_thread_bg_policy(proc->task, target_threadid);
-                       }
-                       error = copyout((int *)&intval, (user_addr_t)attrp, sizeof(int));
-                       break;
-
-               case PROC_POLICY_ACTION_SET: 
-                       error = copyin((user_addr_t)attrp, (int *)&intval, sizeof(int));
-                       if (error != 0)
-                               goto out;
-                       if (intval > PROC_POLICY_BG_ALL) {
-                               error = EINVAL;
-                               goto out;       
-                       }
-                       if (scope == PROC_POLICY_SCOPE_PROCESS) {
-                               error = proc_set_bgtaskpolicy(proc->task, intval);
-                       } else {
-                               /* thread scope */
-                               error = proc_set_bgthreadpolicy(proc->task, target_threadid, intval);
-                       }
-                       break;
-
-               case PROC_POLICY_ACTION_ADD: 
-                       error = copyin((user_addr_t)attrp, (int *)&intval, sizeof(int));
-                       if (error != 0)
-                               goto out;
-                       if (intval > PROC_POLICY_BG_ALL) {
-                               error = EINVAL;
-                               goto out;       
-                       }
-                       if (scope == PROC_POLICY_SCOPE_PROCESS) {
-                               error = proc_add_bgtaskpolicy(proc->task, intval);
-                       } else {
-                               /* thread scope */
-                               error = proc_add_bgthreadpolicy(proc->task, target_threadid, intval);
-                       }
-                       break;
-
-               case PROC_POLICY_ACTION_REMOVE: 
-                       error = copyin((user_addr_t)attrp, (int *)&intval, sizeof(int));
-                       if (error != 0)
-                               goto out;
-                       if (intval > PROC_POLICY_BG_ALL) {
-                               error = EINVAL;
-                               goto out;       
-                       }
-                       if (scope == PROC_POLICY_SCOPE_PROCESS) {
-                               error = proc_remove_bgtaskpolicy(proc->task, intval);
-                       } else {
-                               /* thread scope */
-                               error = proc_remove_bgthreadpolicy(proc->task, target_threadid, intval);
-                       }
-                       break;
-               
-               case PROC_POLICY_ACTION_APPLY:
-                       if (scope == PROC_POLICY_SCOPE_PROCESS) {
-                               error = proc_apply_bgtaskpolicy(proc->task);
-                       } else {
-                               /* thread scope */
-                               error = proc_apply_bgthreadpolicy(proc->task, target_threadid);
-                       }       
-                       break;
-               
-               case PROC_POLICY_ACTION_RESTORE:
-                       if (scope == PROC_POLICY_SCOPE_PROCESS) {
-                               error = proc_restore_bgtaskpolicy(proc->task);
-                       } else {
-                               /* thread scope */
-                               error = proc_restore_bgthreadpolicy(proc->task, target_threadid);
-                       }
-                       break;
-               
-               case PROC_POLICY_ACTION_DENYINHERIT:
-                       error = proc_denyinherit_policy(proc->task);
-                       break;
-               
-               case PROC_POLICY_ACTION_DENYSELFSET:
-                       error = proc_denyselfset_policy(proc->task);
-                       break;
-               
-               default:
-                       return(EINVAL);
-       }
-
-out:
-       return(error);
-}
-
-static int 
-handle_hwaccess(__unused int scope, __unused int action, __unused int policy, int policy_subtype, __unused user_addr_t attrp, __unused proc_t proc, __unused uint64_t target_threadid)
-{
-       switch(policy_subtype) {
-               case PROC_POLICY_HWACCESS_NONE:
-               case PROC_POLICY_HWACCESS_DISK:
-               case PROC_POLICY_HWACCESS_GPU:
-               case PROC_POLICY_HWACCESS_NETWORK:
-               case PROC_POLICY_HWACCESS_CPU:
-                       break;
-               default:
-                       return(EINVAL); 
-       }
-       return(0);
-}
-
-static int 
-handle_lowresrouce(__unused int scope, int action, __unused int policy, int policy_subtype, __unused user_addr_t attrp, proc_t proc, __unused uint64_t target_threadid)
+static int
+handle_lowresource(__unused int scope, int action, __unused int policy, int policy_subtype, __unused user_addr_t attrp, proc_t proc, __unused uint64_t target_threadid)
 {
        int error = 0;
 
@@ -337,8 +198,14 @@ handle_lowresrouce(__unused int scope, int action, __unused int policy, int poli
 static int 
 handle_resourceuse(__unused int scope, __unused int action, __unused int policy, int policy_subtype, user_addr_t attrp, proc_t proc, __unused uint64_t target_threadid)
 {
-       proc_policy_cpuusage_attr_t cpuattr;
-       int error = 0;
+       proc_policy_cpuusage_attr_t     cpuattr;
+#if CONFIG_MACF
+       proc_t                          curp = current_proc();
+#endif
+       int                             entitled = TRUE;
+       uint64_t                        interval = -1ULL;       
+       int                             error = 0;
+       uint8_t                         percentage;
 
        switch(policy_subtype) {
                case PROC_POLICY_RUSAGE_NONE:
@@ -355,30 +222,61 @@ handle_resourceuse(__unused int scope, __unused int action, __unused int policy,
                        break;
        }
 
+#if CONFIG_MACF
+       if (curp != proc) {
+               /* the cpumon entitlement manages messing with CPU limits on self */
+               error = mac_proc_check_sched(curp, proc);
+               if (error)
+                       return error;
+       }
+
+       /*
+        * Allow a process to change CPU usage monitor parameters, unless a MAC policy
+        * overrides it with an entitlement check.
+        */
+       entitled = (mac_proc_check_cpumon(curp) == 0) ? TRUE : FALSE;
+#endif
+
        switch (action) {
                case PROC_POLICY_ACTION_GET: 
                        error = proc_get_task_ruse_cpu(proc->task, &cpuattr.ppattr_cpu_attr,
-                                        &cpuattr.ppattr_cpu_percentage,
+                                        &percentage,
                                         &cpuattr.ppattr_cpu_attr_interval,
                                         &cpuattr.ppattr_cpu_attr_deadline);
-                       if (error == 0)
+                       if (error == 0) {
+                               cpuattr.ppattr_cpu_percentage = percentage;
+                               cpuattr.ppattr_cpu_attr_interval /= NSEC_PER_SEC;
                                error = copyout((proc_policy_cpuusage_attr_t *)&cpuattr, (user_addr_t)attrp, sizeof(proc_policy_cpuusage_attr_t));
+                       }
                        break;
 
                case PROC_POLICY_ACTION_APPLY: 
                case PROC_POLICY_ACTION_SET: 
                        error = copyin((user_addr_t)attrp, (proc_policy_cpuusage_attr_t *)&cpuattr, sizeof(proc_policy_cpuusage_attr_t));
+                       if (error != 0) {
+                               return (error);
+                       }
+
+                       /*
+                        * The process_policy API uses seconds as the units for the interval,
+                        * but the mach task policy SPI uses nanoseconds. Do the conversion,
+                        * but preserve -1 as it has special meaning.
+                        */
+                       if (cpuattr.ppattr_cpu_attr_interval != -1ULL) {
+                               interval = cpuattr.ppattr_cpu_attr_interval * NSEC_PER_SEC;
+                       } else {
+                               interval = -1ULL;
+                       }
 
-                       if (error == 0) {
                        error = proc_set_task_ruse_cpu(proc->task, cpuattr.ppattr_cpu_attr, 
                                        cpuattr.ppattr_cpu_percentage, 
-                                       cpuattr.ppattr_cpu_attr_interval, 
-                                       cpuattr.ppattr_cpu_attr_deadline); 
-                       }
+                                       interval, 
+                                       cpuattr.ppattr_cpu_attr_deadline,
+                                       entitled); 
                        break;
 
                case PROC_POLICY_ACTION_RESTORE:
-                       error = proc_clear_task_ruse_cpu(proc->task);
+                       error = proc_clear_task_ruse_cpu(proc->task, entitled);
                        break;
 
                default:
@@ -390,170 +288,237 @@ handle_resourceuse(__unused int scope, __unused int action, __unused int policy,
        return(error);
 }
 
-#if CONFIG_EMBEDDED
-static int 
-handle_applifecycle(__unused int scope, int action, __unused int policy, int policy_subtype, user_addr_t attrp, proc_t proc, uint64_t target_threadid)
+
+static int
+handle_apptype(         int scope,
+                        int action,
+               __unused int policy,
+                        int policy_subtype,
+               __unused user_addr_t attrp,
+                        proc_t target_proc,
+               __unused uint64_t target_threadid)
 {
+       int error = 0;
+
+       if (scope != PROC_POLICY_SCOPE_PROCESS)
+               return (EINVAL);
+
+       /* Temporary compatibility with old importance donation interface until libproc is moved to new boost calls */
+       switch (policy_subtype) {
+               case PROC_POLICY_IOS_DONATEIMP:
+                       if (action != PROC_POLICY_ACTION_ENABLE)
+                               return (EINVAL);
+                       if (target_proc != current_proc())
+                               return (EINVAL);
+                       
+                       /* PROCESS ENABLE APPTYPE DONATEIMP */
+                       task_importance_mark_donor(target_proc->task, TRUE);
+
+                       return(0);
+
+               case PROC_POLICY_IOS_HOLDIMP:
+                       if (action != PROC_POLICY_ACTION_ENABLE)
+                               return (EINVAL);
+                       if (target_proc != current_proc())
+                               return (EINVAL);
+
+                       /* PROCESS ENABLE APPTYPE HOLDIMP */
+                       error = task_importance_hold_legacy_external_assertion(current_task(), 1);
+
+                       return(error);
+
+               case PROC_POLICY_IOS_DROPIMP:
+                       if (action != PROC_POLICY_ACTION_ENABLE)
+                               return (EINVAL);
+                       if (target_proc != current_proc())
+                               return (EINVAL);
+
+                       /* PROCESS ENABLE APPTYPE DROPIMP */
+                       error = task_importance_drop_legacy_external_assertion(current_task(), 1);
+
+                       return(error);
+
+               default:
+                       /* continue to TAL handling */
+                       break;
+       }
+
+       if (policy_subtype != PROC_POLICY_OSX_APPTYPE_TAL)
+               return (EINVAL);
+
+       /* need to be super user to do this */
+       if (kauth_cred_issuser(kauth_cred_get()) == 0)
+               return (EPERM);
+
+       if (proc_task_is_tal(target_proc->task) == FALSE)
+               return (EINVAL);
+
+       switch (action) {
+               case PROC_POLICY_ACTION_ENABLE:
+                       /* PROCESS ENABLE APPTYPE TAL */
+                       proc_set_task_policy(target_proc->task, THREAD_NULL,
+                                             TASK_POLICY_ATTRIBUTE, TASK_POLICY_TAL,
+                                             TASK_POLICY_ENABLE);
+                       break;
+               case PROC_POLICY_ACTION_DISABLE:
+                       /* PROCESS DISABLE APPTYPE TAL */
+                       proc_set_task_policy(target_proc->task, THREAD_NULL,
+                                             TASK_POLICY_ATTRIBUTE, TASK_POLICY_TAL,
+                                             TASK_POLICY_DISABLE);
+                       break;
+               default:
+                       return (EINVAL);
+                       break;
+       }
+
+       return(0);
+}
 
+static int
+handle_boost(int scope,
+             int action,
+    __unused int policy,
+             int policy_subtype,
+    __unused user_addr_t attrp,
+             proc_t target_proc,
+    __unused uint64_t target_threadid)
+{
        int error = 0;
-       int state = 0, oldstate = 0; 
-       int noteval = 0;
 
-       
+       assert(policy == PROC_POLICY_BOOST);
+
+       if (scope != PROC_POLICY_SCOPE_PROCESS)
+               return (EINVAL);
+
+       if (target_proc != current_proc())
+               return (EINVAL);
 
        switch(policy_subtype) {
-               case PROC_POLICY_APPLIFE_NONE:
-                       error = 0;
-                       break;
+               case PROC_POLICY_IMP_IMPORTANT:
+                       if (task_is_importance_receiver_type(target_proc->task) == FALSE)
+                               return (EINVAL);
 
-               case PROC_POLICY_APPLIFE_STATE:
-#if CONFIG_MACF
-                       error = mac_proc_check_sched(current_proc(), proc);
-                       if (error) 
-                               goto out;
-#endif
                        switch (action) {
-                               case PROC_POLICY_ACTION_GET :
-                                       state = proc_lf_getappstate(proc->task);
-                                       error = copyout((int *)&state, (user_addr_t)attrp, sizeof(int));
+                               case PROC_POLICY_ACTION_HOLD:
+                                       /* PROCESS HOLD BOOST IMPORTANT */
+                                       error = task_importance_hold_legacy_external_assertion(current_task(), 1);
                                        break;
-                               case PROC_POLICY_ACTION_APPLY :
-                               case PROC_POLICY_ACTION_SET :
-                                       error = copyin((user_addr_t)attrp, (int  *)&state, sizeof(int));
-                                       if ((error == 0) && (state != TASK_APPSTATE_NONE)) {
-                                               oldstate = proc_lf_getappstate(proc->task);
-                                               error = proc_lf_setappstate(proc->task, state);
-                                               if (error == 0) {
-                                                       switch (state) {
-                                                               case TASK_APPSTATE_ACTIVE:
-                                                                       noteval = NOTE_APPACTIVE;
-                                                                       break;
-                                                               case TASK_APPSTATE_BACKGROUND:
-                                                                       noteval = NOTE_APPBACKGROUND;
-                                                                       break;
-                                                               case TASK_APPSTATE_NONUI:
-                                                                       noteval = NOTE_APPNONUI;
-                                                                       break;
-                                                               case TASK_APPSTATE_INACTIVE:
-                                                                       noteval = NOTE_APPINACTIVE;
-                                                                       break;
-                                                       }
-                                       
-                                                       proc_lock(proc);        
-                                                       proc_knote(proc, noteval);
-                                                       proc_unlock(proc);      
-                                               }
-                                       }
+                               case PROC_POLICY_ACTION_DROP:
+                                       /* PROCESS DROP BOOST IMPORTANT */
+                                       error = task_importance_drop_legacy_external_assertion(current_task(), 1);
                                        break;
-
                                default:
-                                       error = EINVAL;
+                                       error = (EINVAL);
                                        break;
                        }
                        break;
 
-               case PROC_POLICY_APPLIFE_DEVSTATUS:
+               case PROC_POLICY_IMP_DONATION:
 #if CONFIG_MACF
-                       /* ToDo - this should be a generic check, since we could potentially hang other behaviours here. */
-                       error = mac_proc_check_suspend_resume(current_proc(), MAC_PROC_CHECK_HIBERNATE);
-                       if (error) {
-                               error = EPERM;
-                               goto out;
-                       }
+                       error = mac_proc_check_sched(current_proc(), target_proc);
+                       if (error) return error;
 #endif
-                       if (action == PROC_POLICY_ACTION_APPLY) {
-                               /* Used as a freeze hint */
-                               memorystatus_on_inactivity(-1);
-                               
-                               /* in future use devicestatus for pid_socketshutdown() */
-                               error = 0;
-                        } else {
-                               error = EINVAL;
+                       switch (action) {
+                               case PROC_POLICY_ACTION_SET:
+                                       /* PROCESS SET BOOST DONATION */
+                                       task_importance_mark_donor(target_proc->task, TRUE);
+                                       break;
+                               default:
+                                       error = (EINVAL);
+                                       break;
                        }
                        break;
 
-               case PROC_POLICY_APPLIFE_PIDBIND:
-#if CONFIG_MACF
-                       error = mac_proc_check_suspend_resume(current_proc(), MAC_PROC_CHECK_PIDBIND);
-                       if (error) {
-                               error = EPERM;
-                               goto out;
-                       }
-#endif
-                       error = copyin((user_addr_t)attrp, (int  *)&state, sizeof(int));
-                       if (error != 0)
-                               goto out;
-                       if (action == PROC_POLICY_ACTION_APPLY) {
-                               /* bind the thread in target_thread in current process to target_proc */
-                               error = proc_lf_pidbind(current_task(), target_threadid, proc->task, state);
-                        } else
-                               error = EINVAL;
-                       break;
                default:
-                       error = EINVAL;
-                       break;  
+                       error = (EINVAL);
+                       break;
        }
 
-out:
        return(error);
 }
-#endif /* CONFIG_EMBEDDED */
 
 
-static int 
-handle_apptype(__unused int scope, int action, __unused int policy, int policy_subtype, __unused user_addr_t attrp, proc_t target_proc, __unused uint64_t target_threadid)
+/* 
+ * KPI to determine if a pid is currently backgrounded. 
+ * Returns ESRCH if pid cannot be found or has started exiting.
+ * Returns EINVAL if state is NULL.
+ * Sets *state to 1 if pid is backgrounded, and 0 otherwise.
+ */
+int
+proc_pidbackgrounded(pid_t pid, uint32_t* state)
 {
-       int error = 0;
+       proc_t target_proc = PROC_NULL;
 
-       switch(policy_subtype) {
-#if !CONFIG_EMBEDDED
-               case PROC_POLICY_OSX_APPTYPE_TAL:
-                       /* need to be super user to do this */
-                       if (kauth_cred_issuser(kauth_cred_get()) == 0) {
-                               error = EPERM;
-                               goto out;
-                       }
-                       break;
-               case PROC_POLICY_OSX_APPTYPE_DASHCLIENT:
-                       /* no special priv needed */
-                       break;
-#endif /* !CONFIG_EMBEDDED */
-               case PROC_POLICY_OSX_APPTYPE_NONE:
-#if CONFIG_EMBEDDED
-               case PROC_POLICY_IOS_RESV1_APPTYPE:
-               case PROC_POLICY_IOS_APPLE_DAEMON:
-               case PROC_POLICY_IOS_APPTYPE:
-               case PROC_POLICY_IOS_NONUITYPE:
-#endif /* CONFIG_EMBEDDED */
-                       return(ENOTSUP);
-                       break;
-               default:
-                       return(EINVAL); 
-       }
+       if (state == NULL)
+               return(EINVAL); 
 
-       switch (action) {
-               case PROC_POLICY_ACTION_ENABLE:
-                       /* reapply the app foreground/background policy */
-                       error = proc_enable_task_apptype(target_proc->task, policy_subtype);
-                       break;
-               case PROC_POLICY_ACTION_DISABLE: 
-                       /* remove the app foreground/background policy */
-                       error = proc_disable_task_apptype(target_proc->task, policy_subtype);
-                       break;
-               default:
-                       error = EINVAL;
-                       break;
+       target_proc = proc_find(pid);
+
+       if (target_proc == PROC_NULL)
+               return(ESRCH);
+
+       if ( proc_get_effective_task_policy(target_proc->task, TASK_POLICY_DARWIN_BG) ) {
+               *state = 1;
+       } else {
+               *state = 0;
        }
-                               
-#if !CONFIG_EMBEDDED
-out:
-#endif /* !CONFIG_EMBEDDED */
-       return(error);
+
+       proc_rele(target_proc);
+       return (0);
 }
 
+/*
+ * Get the darwin background state of the originator. If the current
+ * process app type is App, then it is the originator, else if it is
+ * a Daemon, then creator of the Resource Accounting attribute of
+ * the current thread voucher is the originator of the work.
+ */
+int
+proc_get_originatorbgstate(uint32_t *is_backgrounded)
+{
+       uint32_t bgstate;
+       proc_t p = current_proc();
+       uint32_t flagsp;
+       kern_return_t kr;
+       pid_t pid;
+       int ret;
+       thread_t thread = current_thread();
+
+       bgstate = proc_get_effective_thread_policy(thread, TASK_POLICY_DARWIN_BG);
+       
+       /* If current thread or task backgrounded, return background */
+       if (bgstate) {
+               *is_backgrounded = 1;
+               return 0;
+       }
+
+       /* Check if current process app type is App, then return foreground */
+       proc_get_darwinbgstate(p->task, &flagsp);
+       if ((flagsp & PROC_FLAG_APPLICATION) == PROC_FLAG_APPLICATION) {
+               *is_backgrounded = 0;
+               return 0;
+       }
+
+       /*
+        * Get the current voucher origin pid and it's bgstate.The pid
+        * returned here might not be valid or may have been recycled.
+        */
+       kr = thread_get_current_voucher_origin_pid(&pid);
+       if (kr != KERN_SUCCESS) {
+               if (kr == KERN_INVALID_TASK)
+                       return ESRCH;
+               else if (kr == KERN_INVALID_VALUE)
+                       return ENOATTR;
+               else
+                       return EINVAL;
+       }
+
+       ret = proc_pidbackgrounded(pid, is_backgrounded);
+       return ret;
+}
 
 int
-proc_apply_resource_actions(void * bsdinfo, int type, int action)
+proc_apply_resource_actions(void * bsdinfo, __unused int type, int action)
 {
        proc_t p = (proc_t)bsdinfo;
 
@@ -571,9 +536,7 @@ proc_apply_resource_actions(void * bsdinfo, int type, int action)
                        break;
 
                case PROC_POLICY_RSRCACT_NOTIFY_KQ:
-                       proc_lock(p);
-                       proc_knote(p, NOTE_RESOURCEEND | (type & 0xff));
-                       proc_unlock(p);
+                       /* not implemented */
                        break;
                
                case PROC_POLICY_RSRCACT_NOTIFY_EXC:
@@ -584,7 +547,6 @@ proc_apply_resource_actions(void * bsdinfo, int type, int action)
        return(0);
 }
 
-
 int
 proc_restore_resource_actions(void * bsdinfo, __unused int type, int action)
 {