]> git.saurik.com Git - apple/xnu.git/blobdiff - bsd/kern/kern_prot.c
xnu-3789.70.16.tar.gz
[apple/xnu.git] / bsd / kern / kern_prot.c
index e90c68c55b80b7109f686800d1ca750f684c7ced..9d825afcbf94c302d8011f8fdeb5cc9c58ab22c0 100644 (file)
@@ -95,8 +95,7 @@
 #include <sys/timeb.h>
 #include <sys/times.h>
 #include <sys/malloc.h>
-
-#define chgproccnt_ok(p) 1
+#include <sys/persona.h>
 
 #include <security/audit/audit.h>
 
@@ -581,7 +580,7 @@ setsid(proc_t p, __unused struct setsid_args *uap, int32_t *retval)
  * XXX:                Belongs in kern_proc.c
  */
 int
-setpgid(proc_t curp, register struct setpgid_args *uap, __unused int32_t *retval)
+setpgid(proc_t curp, struct setpgid_args *uap, __unused int32_t *retval)
 {
        proc_t targp = PROC_NULL;       /* target process */
        struct pgrp *pg = PGRP_NULL;    /* target pgrp */
@@ -778,7 +777,7 @@ setuid(proc_t p, struct setuid_args *uap, __unused int32_t *retval)
                         * may be able to decrement the proc count of B before we can increment it. This results in a panic.
                         * Incrementing the proc count of the target ruid, B, before setting the process credentials prevents this race.
                         */
-                       if (ruid != KAUTH_UID_NONE && chgproccnt_ok(p)) {
+                       if (ruid != KAUTH_UID_NONE && !proc_has_persona(p)) {
                                (void)chgproccnt(ruid, 1);
                        }
 
@@ -797,7 +796,7 @@ setuid(proc_t p, struct setuid_args *uap, __unused int32_t *retval)
                                 * We didn't successfully switch to the new ruid, so decrement
                                 * the procs/uid count that we incremented above.
                                 */
-                               if (ruid != KAUTH_UID_NONE && chgproccnt_ok(p)) {
+                               if (ruid != KAUTH_UID_NONE && !proc_has_persona(p)) {
                                        (void)chgproccnt(ruid, -1);
                                }
                                kauth_cred_unref(&my_new_cred);
@@ -816,7 +815,7 @@ setuid(proc_t p, struct setuid_args *uap, __unused int32_t *retval)
                         * If we've updated the ruid, decrement the count of procs running
                         * under the previous ruid
                         */
-                       if (ruid != KAUTH_UID_NONE && chgproccnt_ok(p)) {
+                       if (ruid != KAUTH_UID_NONE && !proc_has_persona(p)) {
                                (void)chgproccnt(my_pcred->cr_ruid, -1);
                        }
                }
@@ -1026,7 +1025,7 @@ setreuid(proc_t p, struct setreuid_args *uap, __unused int32_t *retval)
                         * may be able to decrement the proc count of B before we can increment it. This results in a panic.
                         * Incrementing the proc count of the target ruid, B, before setting the process credentials prevents this race.
                         */
-                       if (ruid != KAUTH_UID_NONE && chgproccnt_ok(p)) {
+                       if (ruid != KAUTH_UID_NONE && !proc_has_persona(p)) {
                                (void)chgproccnt(ruid, 1);
                        }
 
@@ -1041,7 +1040,7 @@ setreuid(proc_t p, struct setreuid_args *uap, __unused int32_t *retval)
                         */
                        if (p->p_ucred != my_cred) {
                                proc_ucred_unlock(p);
-                               if (ruid != KAUTH_UID_NONE && chgproccnt_ok(p)) {
+                               if (ruid != KAUTH_UID_NONE && !proc_has_persona(p)) {
                                        /*
                                         * We didn't successfully switch to the new ruid, so decrement
                                         * the procs/uid count that we incremented above.
@@ -1061,7 +1060,7 @@ setreuid(proc_t p, struct setreuid_args *uap, __unused int32_t *retval)
                        OSBitOrAtomic(P_SUGID, &p->p_flag);
                        proc_ucred_unlock(p);
 
-                       if (ruid != KAUTH_UID_NONE && chgproccnt_ok(p)) {
+                       if (ruid != KAUTH_UID_NONE && !proc_has_persona(p)) {
                                /*
                                 * We switched to a new ruid, so decrement the count of procs running
                                 * under the previous ruid
@@ -1985,12 +1984,25 @@ setlogin(proc_t p, struct setlogin_args *uap, __unused int32_t *retval)
  */
 int
 set_security_token(proc_t p)
+{
+       return set_security_token_task_internal(p, p->task);
+}
+
+/*
+ * Set the secrity token of the task with current euid and eguid
+ * The function takes a proc and a task, where proc->task might point to a
+ * different task if called from exec.
+ */
+
+int
+set_security_token_task_internal(proc_t p, void *t)
 {
        security_token_t sec_token;
        audit_token_t    audit_token;
        kauth_cred_t my_cred;
        posix_cred_t my_pcred;
        host_priv_t host_priv;
+       task_t task = t;
 
        /*
         * Don't allow a vfork child to override the parent's token settings
@@ -1998,7 +2010,7 @@ set_security_token(proc_t p)
         * suffer along using the parent's token until the exec().  It's all
         * undefined behavior anyway, right?
         */
-       if (p->task == current_task()) {
+       if (task == current_task()) {
                uthread_t        uthread;
                uthread = (uthread_t)get_bsdthread_info(current_thread());
                if (uthread->uu_flag & UT_VFORK)
@@ -2046,11 +2058,11 @@ set_security_token(proc_t p)
        /* 
         * Update the pid an proc name for importance base if any
         */
-       task_importance_update_owner_info(p->task);
+       task_importance_update_owner_info(task);
 #endif
 
        return (host_security_set_task_token(host_security_self(),
-                                          p->task,
+                                          task,
                                           sec_token,
                                           audit_token,
                                           host_priv) != KERN_SUCCESS);