X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/b226f5e54a60dc81db17b1260381d7dbfea3cdf1..0a7de7458d150b5d4dffc935ba399be265ef0a1a:/bsd/kern/kern_fork.c diff --git a/bsd/kern/kern_fork.c b/bsd/kern/kern_fork.c index 2fb8a03d6..772c16355 100644 --- a/bsd/kern/kern_fork.c +++ b/bsd/kern/kern_fork.c @@ -2,7 +2,7 @@ * Copyright (c) 2000-2007, 2015 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ - * + * * This file contains Original Code and/or Modifications of Original Code * as defined in and that are subject to the Apple Public Source License * Version 2.0 (the 'License'). You may not use this file except in @@ -11,10 +11,10 @@ * unlawful or unlicensed copies of an Apple operating system, or to * circumvent, violate, or enable the circumvention or violation of, any * terms of an Apple operating system software license agreement. - * + * * Please obtain a copy of the License at * http://www.opensource.apple.com/apsl/ and read it before using this file. - * + * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, @@ -22,7 +22,7 @@ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. * Please see the License for the specific language governing rights and * limitations under the License. - * + * * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ */ /* Copyright (c) 1995, 1997 Apple Computer, Inc. All Rights Reserved */ @@ -137,9 +137,9 @@ static void (*dtrace_proc_waitfor_hook)(proc_t) = NULL; #include #include -#include /* for shmfork() */ -#include /* for thread_create() */ -#include /* for thread_resume() */ +#include /* for shmfork() */ +#include /* for thread_create() */ +#include /* for thread_resume() */ #include @@ -153,23 +153,24 @@ extern void act_thread_catt(void *ctx); void thread_set_child(thread_t child, int pid); void *act_thread_csave(void); extern boolean_t task_is_exec_copy(task_t); +int nextpidversion = 0; thread_t cloneproc(task_t, coalition_t *, proc_t, int, int); proc_t forkproc(proc_t); void forkproc_free(proc_t); thread_t fork_create_child(task_t parent_task, - coalition_t *parent_coalitions, - proc_t child, - int inherit_memory, - int is_64bit_addr, - int is_64bit_data, - int in_exec); + coalition_t *parent_coalitions, + proc_t child, + int inherit_memory, + int is_64bit_addr, + int is_64bit_data, + int in_exec); void proc_vfork_begin(proc_t parent_proc); void proc_vfork_end(proc_t parent_proc); -#define DOFORK 0x1 /* fork() system call */ -#define DOVFORK 0x2 /* vfork() system call */ +#define DOFORK 0x1 /* fork() system call */ +#define DOVFORK 0x2 /* vfork() system call */ /* * proc_vfork_begin @@ -212,10 +213,12 @@ proc_vfork_end(proc_t parent_proc) { proc_lock(parent_proc); parent_proc->p_vforkcnt--; - if (parent_proc->p_vforkcnt < 0) + if (parent_proc->p_vforkcnt < 0) { panic("vfork cnt is -ve"); - if (parent_proc->p_vforkcnt == 0) + } + if (parent_proc->p_vforkcnt == 0) { parent_proc->p_lflag &= ~P_LVFORK; + } proc_unlock(parent_proc); } @@ -305,7 +308,7 @@ vfork(proc_t parent_proc, __unused struct vfork_args *uap, int32_t *retval) proc_t child_proc = ut->uu_proc; retval[0] = child_proc->p_pid; - retval[1] = 1; /* flag child return for user space */ + retval[1] = 1; /* flag child return for user space */ /* * Drop the signal lock on the child which was taken on our @@ -320,7 +323,7 @@ vfork(proc_t parent_proc, __unused struct vfork_args *uap, int32_t *retval) ut->uu_flag &= ~UT_VFORKING; } - return (err); + return err; } @@ -376,7 +379,7 @@ fork1(proc_t parent_proc, thread_t *child_threadp, int kind, coalition_t *coalit { thread_t parent_thread = (thread_t)current_thread(); uthread_t parent_uthread = (uthread_t)get_bsdthread_info(parent_thread); - proc_t child_proc = NULL; /* set in switch, but compiler... */ + proc_t child_proc = NULL; /* set in switch, but compiler... */ thread_t child_thread = NULL; uid_t uid; int count; @@ -403,7 +406,7 @@ fork1(proc_t parent_proc, thread_t *child_threadp, int kind, coalition_t *coalit #endif proc_list_unlock(); tablefull("proc"); - return (EAGAIN); + return EAGAIN; } proc_list_unlock(); @@ -425,7 +428,7 @@ fork1(proc_t parent_proc, thread_t *child_threadp, int kind, coalition_t *coalit */ panic("The per-user process limit has been hit; parent pid=%d, uid=%d", parent_proc->p_pid, uid); #endif - err = EAGAIN; + err = EAGAIN; goto bad; } @@ -435,12 +438,12 @@ fork1(proc_t parent_proc, thread_t *child_threadp, int kind, coalition_t *coalit * it to fork. This is an advisory-only check. */ err = mac_proc_check_fork(parent_proc); - if (err != 0) { + if (err != 0) { goto bad; } #endif - switch(kind) { + switch (kind) { case PROC_CREATE_VFORK: /* * Prevent a vfork while we are in vfork(); we should @@ -551,7 +554,7 @@ fork1(proc_t parent_proc, thread_t *child_threadp, int kind, coalition_t *coalit /* XXX is this actually necessary, given syscall return? */ thread_set_child(parent_thread, child_proc->p_pid); - child_proc->p_acflag = AFORK; /* forked but not exec'ed */ + child_proc->p_acflag = AFORK; /* forked but not exec'ed */ /* * Preserve synchronization semantics of vfork. If @@ -559,7 +562,7 @@ fork1(proc_t parent_proc, thread_t *child_threadp, int kind, coalition_t *coalit * on child, and sleep on our proc (in case of exit). */ child_proc->p_lflag |= P_LPPWAIT; - pinsertchild(parent_proc, child_proc); /* set visible */ + pinsertchild(parent_proc, child_proc); /* set visible */ break; @@ -572,7 +575,7 @@ fork1(proc_t parent_proc, thread_t *child_threadp, int kind, coalition_t *coalit */ spawn = 1; - /* FALLSTHROUGH */ + /* FALLSTHROUGH */ case PROC_CREATE_FORK: /* @@ -582,10 +585,10 @@ fork1(proc_t parent_proc, thread_t *child_threadp, int kind, coalition_t *coalit * differences. Contrarily, spawned processes do not inherit. */ if ((child_thread = cloneproc(parent_proc->task, - spawn ? coalitions : NULL, - parent_proc, - spawn ? FALSE : TRUE, - FALSE)) == NULL) { + spawn ? coalitions : NULL, + parent_proc, + spawn ? FALSE : TRUE, + FALSE)) == NULL) { /* Failed to create thread */ err = EAGAIN; goto bad; @@ -641,11 +644,11 @@ fork1(proc_t parent_proc, thread_t *child_threadp, int kind, coalition_t *coalit */ thread_set_child(child_thread, child_proc->p_pid); - child_proc->p_acflag = AFORK; /* forked but not exec'ed */ + child_proc->p_acflag = AFORK; /* forked but not exec'ed */ #if CONFIG_DTRACE dtrace_proc_fork(parent_proc, child_proc, spawn); -#endif /* CONFIG_DTRACE */ +#endif /* CONFIG_DTRACE */ if (!spawn) { /* * Of note, we need to initialize the bank context behind @@ -675,7 +678,7 @@ bad: (void)chgproccnt(uid, -1); } - return (err); + return err; } @@ -705,7 +708,7 @@ vfork_return(proc_t child_proc, int32_t *retval, int rval) proc_t parent_proc = get_bsdtask_info(parent_task); thread_t th = current_thread(); uthread_t uth = get_bsdthread_info(th); - + act_thread_catt(uth->uu_userstate); /* clear vfork state in parent proc structure */ @@ -731,7 +734,7 @@ vfork_return(proc_t child_proc, int32_t *retval, int rval) if (retval) { retval[0] = rval; - retval[1] = 0; /* mark parent */ + retval[1] = 0; /* mark parent */ } } @@ -750,7 +753,7 @@ vfork_return(proc_t child_proc, int32_t *retval, int rval) * is_64bit_addr TRUE, if the child being created will * be associated with a 64 bit address space * is_64bit_data TRUE if the child being created will use a - 64-bit register state + * 64-bit register state * in_exec TRUE, if called from execve or posix spawn set exec * FALSE, if called from fork or vfexec * @@ -772,26 +775,26 @@ vfork_return(proc_t child_proc, int32_t *retval, int rval) */ thread_t fork_create_child(task_t parent_task, - coalition_t *parent_coalitions, - proc_t child_proc, - int inherit_memory, - int is_64bit_addr, - int is_64bit_data, - int in_exec) + coalition_t *parent_coalitions, + proc_t child_proc, + int inherit_memory, + int is_64bit_addr, + int is_64bit_data, + int in_exec) { - thread_t child_thread = NULL; - task_t child_task; - kern_return_t result; + thread_t child_thread = NULL; + task_t child_task; + kern_return_t result; /* Create a new task for the child process */ result = task_create_internal(parent_task, - parent_coalitions, - inherit_memory, - is_64bit_addr, - is_64bit_data, - TF_LRETURNWAIT | TF_LRETURNWAITER, /* All created threads will wait in task_wait_to_return */ - in_exec ? TPF_EXEC_COPY : TPF_NONE, /* Mark the task exec copy if in execve */ - &child_task); + parent_coalitions, + inherit_memory, + is_64bit_addr, + is_64bit_data, + TF_LRETURNWAIT | TF_LRETURNWAITER, /* All created threads will wait in task_wait_to_return */ + in_exec ? TPF_EXEC_COPY : TPF_NONE, /* Mark the task exec copy if in execve */ + &child_task); if (result != KERN_SUCCESS) { printf("%s: task_create_internal failed. Code: %d\n", __func__, result); @@ -810,24 +813,26 @@ fork_create_child(task_t parent_task, set_bsdtask_info(child_task, child_proc); /* Propagate CPU limit timer from parent */ - if (timerisset(&child_proc->p_rlim_cpu)) + if (timerisset(&child_proc->p_rlim_cpu)) { task_vtimer_set(child_task, TASK_VTIMER_RLIM); + } /* * Set child process BSD visible scheduler priority if nice value * inherited from parent */ - if (child_proc->p_nice != 0) + if (child_proc->p_nice != 0) { resetpriority(child_proc); + } /* * Create a new thread for the child process * The new thread is waiting on the event triggered by 'task_clear_return_wait' */ result = thread_create_waiting(child_task, - (thread_continue_t)task_wait_to_return, - task_get_return_wait_event(child_task), - &child_thread); + (thread_continue_t)task_wait_to_return, + task_get_return_wait_event(child_task), + &child_thread); if (result != KERN_SUCCESS) { printf("%s: thread_create failed. Code: %d\n", @@ -837,14 +842,14 @@ fork_create_child(task_t parent_task, } /* - * Tag thread as being the first thread in its task. - */ + * Tag thread as being the first thread in its task. + */ thread_set_tag(child_thread, THREAD_TAG_MAINTHREAD); bad: thread_yield_internal(1); - return(child_thread); + return child_thread; } @@ -888,7 +893,7 @@ fork(proc_t parent_proc, __unused struct fork_args *uap, int32_t *retval) thread_t child_thread; int err; - retval[1] = 0; /* flag parent return for user space */ + retval[1] = 0; /* flag parent return for user space */ if ((err = fork1(parent_proc, &child_thread, PROC_CREATE_FORK, NULL)) == 0) { task_t child_task; @@ -911,8 +916,9 @@ fork(proc_t parent_proc, __unused struct fork_args *uap, int32_t *retval) DTRACE_PROC1(create, proc_t, child_proc); #if CONFIG_DTRACE - if ((dtrace_proc_waitfor_hook = dtrace_proc_waitfor_exec_ptr) != NULL) + if ((dtrace_proc_waitfor_hook = dtrace_proc_waitfor_exec_ptr) != NULL) { (*dtrace_proc_waitfor_hook)(child_proc); + } #endif /* "Return" to the child */ @@ -925,7 +931,7 @@ fork(proc_t parent_proc, __unused struct fork_args *uap, int32_t *retval) thread_deallocate(child_thread); } - return(err); + return err; } @@ -996,12 +1002,12 @@ cloneproc(task_t parent_task, coalition_t *parent_coalitions, proc_t parent_proc const int parent_64bit_data = (parent_task == TASK_NULL) ? parent_64bit_addr : task_get_64bit_data(parent_task); child_thread = fork_create_child(parent_task, - parent_coalitions, - child_proc, - inherit_memory, - parent_64bit_addr, - parent_64bit_data, - FALSE); + parent_coalitions, + child_proc, + inherit_memory, + parent_64bit_addr, + parent_64bit_data, + FALSE); if (child_thread == NULL) { /* @@ -1035,7 +1041,7 @@ cloneproc(task_t parent_task, coalition_t *parent_coalitions, proc_t parent_proc */ child_proc->p_stat = SRUN; bad: - return(child_thread); + return child_thread; } @@ -1107,7 +1113,6 @@ forkproc_free(proc_t p) /* Update the audit session proc count */ AUDIT_SESSION_PROCEXIT(p); -#if CONFIG_FINE_LOCK_GROUPS lck_mtx_destroy(&p->p_mlock, proc_mlock_grp); lck_mtx_destroy(&p->p_fdmlock, proc_fdmlock_grp); lck_mtx_destroy(&p->p_ucred_mlock, proc_ucred_mlock_grp); @@ -1115,15 +1120,6 @@ forkproc_free(proc_t p) lck_mtx_destroy(&p->p_dtrace_sprlock, proc_lck_grp); #endif lck_spin_destroy(&p->p_slock, proc_slock_grp); -#else /* CONFIG_FINE_LOCK_GROUPS */ - lck_mtx_destroy(&p->p_mlock, proc_lck_grp); - lck_mtx_destroy(&p->p_fdmlock, proc_lck_grp); - lck_mtx_destroy(&p->p_ucred_mlock, proc_lck_grp); -#if CONFIG_DTRACE - lck_mtx_destroy(&p->p_dtrace_sprlock, proc_lck_grp); -#endif - lck_spin_destroy(&p->p_slock, proc_lck_grp); -#endif /* CONFIG_FINE_LOCK_GROUPS */ /* Release the credential reference */ kauth_cred_unref(&p->p_ucred); @@ -1168,14 +1164,14 @@ forkproc_free(proc_t p) proc_t forkproc(proc_t parent_proc) { - proc_t child_proc; /* Our new process */ - static int nextpid = 0, pidwrap = 0, nextpidversion = 0; + proc_t child_proc; /* Our new process */ + static int nextpid = 0, pidwrap = 0; static uint64_t nextuniqueid = 0; int error = 0; struct session *sessp; uthread_t parent_uthread = (uthread_t)get_bsdthread_info(current_thread()); - MALLOC_ZONE(child_proc, proc_t , sizeof *child_proc, M_PROC, M_WAITOK); + MALLOC_ZONE(child_proc, proc_t, sizeof *child_proc, M_PROC, M_WAITOK); if (child_proc == NULL) { printf("forkproc: M_PROC zone exhausted\n"); goto bad; @@ -1184,7 +1180,7 @@ forkproc(proc_t parent_proc) bzero(child_proc, sizeof *child_proc); MALLOC_ZONE(child_proc->p_stats, struct pstats *, - sizeof *child_proc->p_stats, M_PSTATS, M_WAITOK); + sizeof *child_proc->p_stats, M_PSTATS, M_WAITOK); if (child_proc->p_stats == NULL) { printf("forkproc: M_SUBPROC zone exhausted (p_stats)\n"); FREE_ZONE(child_proc, sizeof *child_proc, M_PROC); @@ -1192,7 +1188,7 @@ forkproc(proc_t parent_proc) goto bad; } MALLOC_ZONE(child_proc->p_sigacts, struct sigacts *, - sizeof *child_proc->p_sigacts, M_SIGACTS, M_WAITOK); + sizeof *child_proc->p_sigacts, M_SIGACTS, M_WAITOK); if (child_proc->p_sigacts == NULL) { printf("forkproc: M_SUBPROC zone exhausted (p_sigacts)\n"); FREE_ZONE(child_proc->p_stats, sizeof *child_proc->p_stats, M_PSTATS); @@ -1216,7 +1212,7 @@ forkproc(proc_t parent_proc) /* - * Find an unused PID. + * Find an unused PID. */ proc_list_lock(); @@ -1233,9 +1229,8 @@ retry: pidwrap = 1; } if (pidwrap != 0) { - /* if the pid stays in hash both for zombie and runniing state */ - if (pfind_locked(nextpid) != PROC_NULL) { + if (pfind_locked(nextpid) != PROC_NULL) { nextpid++; goto retry; } @@ -1243,22 +1238,23 @@ retry: if (pgfind_internal(nextpid) != PGRP_NULL) { nextpid++; goto retry; - } + } if (session_find_internal(nextpid) != SESSION_NULL) { nextpid++; goto retry; - } + } } nprocs++; child_proc->p_pid = nextpid; - child_proc->p_responsible_pid = nextpid; /* initially responsible for self */ - child_proc->p_idversion = nextpidversion++; + child_proc->p_responsible_pid = nextpid; /* initially responsible for self */ + child_proc->p_idversion = OSIncrementAtomic(&nextpidversion); /* kernel process is handcrafted and not from fork, so start from 1 */ child_proc->p_uniqueid = ++nextuniqueid; #if 1 if (child_proc->p_pid != 0) { - if (pfind_locked(child_proc->p_pid) != PROC_NULL) + if (pfind_locked(child_proc->p_pid) != PROC_NULL) { panic("proc in the list already\n"); + } } #endif /* Insert in the hash */ @@ -1300,8 +1296,9 @@ retry: #else /* !CONFIG_EMBEDDED */ child_proc->p_flag = (parent_proc->p_flag & (P_LP64 | P_DISABLE_ASLR | P_SUGID)); #endif /* !CONFIG_EMBEDDED */ - if (parent_proc->p_flag & P_PROFIL) + if (parent_proc->p_flag & P_PROFIL) { startprofclock(child_proc); + } child_proc->p_vfs_iopolicy = (parent_proc->p_vfs_iopolicy & (P_VFS_IOPOLICY_VALID_MASK)); @@ -1315,7 +1312,6 @@ retry: /* update audit session proc count */ AUDIT_SESSION_PROCNEW(child_proc); -#if CONFIG_FINE_LOCK_GROUPS lck_mtx_init(&child_proc->p_mlock, proc_mlock_grp, proc_lck_attr); lck_mtx_init(&child_proc->p_fdmlock, proc_fdmlock_grp, proc_lck_attr); lck_mtx_init(&child_proc->p_ucred_mlock, proc_ucred_mlock_grp, proc_lck_attr); @@ -1323,15 +1319,7 @@ retry: lck_mtx_init(&child_proc->p_dtrace_sprlock, proc_lck_grp, proc_lck_attr); #endif lck_spin_init(&child_proc->p_slock, proc_slock_grp, proc_lck_attr); -#else /* !CONFIG_FINE_LOCK_GROUPS */ - lck_mtx_init(&child_proc->p_mlock, proc_lck_grp, proc_lck_attr); - lck_mtx_init(&child_proc->p_fdmlock, proc_lck_grp, proc_lck_attr); - lck_mtx_init(&child_proc->p_ucred_mlock, proc_lck_grp, proc_lck_attr); -#if CONFIG_DTRACE - lck_mtx_init(&child_proc->p_dtrace_sprlock, proc_lck_grp, proc_lck_attr); -#endif - lck_spin_init(&child_proc->p_slock, proc_lck_grp, proc_lck_attr); -#endif /* !CONFIG_FINE_LOCK_GROUPS */ + klist_init(&child_proc->p_klist); if (child_proc->p_textvp != NULLVP) { @@ -1340,8 +1328,9 @@ retry: if (vnode_getwithref(child_proc->p_textvp) == 0) { error = vnode_ref(child_proc->p_textvp); vnode_put(child_proc->p_textvp); - if (error != 0) + if (error != 0) { child_proc->p_textvp = NULLVP; + } } } @@ -1376,15 +1365,17 @@ retry: bzero(child_proc->p_stats, sizeof(*child_proc->p_stats)); microtime_with_abstime(&child_proc->p_start, &child_proc->p_stats->ps_start); - if (parent_proc->p_sigacts != NULL) + if (parent_proc->p_sigacts != NULL) { (void)memcpy(child_proc->p_sigacts, - parent_proc->p_sigacts, sizeof *child_proc->p_sigacts); - else + parent_proc->p_sigacts, sizeof *child_proc->p_sigacts); + } else { (void)memset(child_proc->p_sigacts, 0, sizeof *child_proc->p_sigacts); + } sessp = proc_session(parent_proc); - if (sessp->s_ttyvp != NULL && parent_proc->p_flag & P_CONTROLT) + if (sessp->s_ttyvp != NULL && parent_proc->p_flag & P_CONTROLT) { OSBitOrAtomic(P_CONTROLT, &child_proc->p_flag); + } session_rele(sessp); /* @@ -1447,8 +1438,8 @@ retry: child_proc->p_memstat_effectivepriority = JETSAM_PRIORITY_DEFAULT; child_proc->p_memstat_requestedpriority = JETSAM_PRIORITY_DEFAULT; child_proc->p_memstat_userdata = 0; - child_proc->p_memstat_idle_start = 0; - child_proc->p_memstat_idle_delta = 0; + child_proc->p_memstat_idle_start = 0; + child_proc->p_memstat_idle_delta = 0; child_proc->p_memstat_memlimit = 0; child_proc->p_memstat_memlimit_active = 0; child_proc->p_memstat_memlimit_inactive = 0; @@ -1460,7 +1451,7 @@ retry: #endif /* CONFIG_MEMORYSTATUS */ bad: - return(child_proc); + return child_proc; } void @@ -1479,7 +1470,7 @@ proc_unlock(proc_t p) void proc_spinlock(proc_t p) { - lck_spin_lock(&p->p_slock); + lck_spin_lock_grp(&p->p_slock, proc_slock_grp); } void @@ -1488,25 +1479,25 @@ proc_spinunlock(proc_t p) lck_spin_unlock(&p->p_slock); } -void +void proc_list_lock(void) { lck_mtx_lock(proc_list_mlock); } -void +void proc_list_unlock(void) { lck_mtx_unlock(proc_list_mlock); } -void +void proc_ucred_lock(proc_t p) { lck_mtx_lock(&p->p_ucred_mlock); } -void +void proc_ucred_unlock(proc_t p) { lck_mtx_unlock(&p->p_ucred_mlock); @@ -1530,9 +1521,9 @@ uthread_zone_init(void) rethrottle_lock_attr = lck_attr_alloc_init(); uthread_zone = zinit(sizeof(struct uthread), - thread_max * sizeof(struct uthread), - THREAD_CHUNK * sizeof(struct uthread), - "uthreads"); + thread_max * sizeof(struct uthread), + THREAD_CHUNK * sizeof(struct uthread), + "uthreads"); } void * @@ -1543,8 +1534,9 @@ uthread_alloc(task_t task, thread_t thread, int noinherit) uthread_t uth_parent; void *ut; - if (uthread_zone == NULL) + if (uthread_zone == NULL) { uthread_zone_init(); + } ut = (void *)zalloc(uthread_zone); bzero(ut, sizeof(struct uthread)); @@ -1554,7 +1546,7 @@ uthread_alloc(task_t task, thread_t thread, int noinherit) uth->uu_thread = thread; lck_spin_init(&uth->uu_rethrottle_lock, rethrottle_lock_grp, - rethrottle_lock_attr); + rethrottle_lock_attr); /* * Thread inherits credential from the creating thread, if both @@ -1565,7 +1557,7 @@ uthread_alloc(task_t task, thread_t thread, int noinherit) * one later, it will be lazily assigned from the task's process. */ uth_parent = (uthread_t)get_bsdthread_info(current_thread()); - if ((noinherit == 0) && task == current_task() && + if ((noinherit == 0) && task == current_task() && uth_parent != NULL && IS_VALID_CRED(uth_parent->uu_ucred)) { /* @@ -1576,28 +1568,30 @@ uthread_alloc(task_t task, thread_t thread, int noinherit) kauth_cred_ref(uth_parent->uu_ucred); uth->uu_ucred = uth_parent->uu_ucred; /* the credential we just inherited is an assumed credential */ - if (uth_parent->uu_flag & UT_SETUID) + if (uth_parent->uu_flag & UT_SETUID) { uth->uu_flag |= UT_SETUID; + } } else { /* sometimes workqueue threads are created out task context */ - if ((task != kernel_task) && (p != PROC_NULL)) + if ((task != kernel_task) && (p != PROC_NULL)) { uth->uu_ucred = kauth_cred_proc_ref(p); - else + } else { uth->uu_ucred = NOCRED; + } } - + if ((task != kernel_task) && p) { - proc_lock(p); if (noinherit != 0) { /* workq threads will not inherit masks */ uth->uu_sigmask = ~workq_threadmask; } else if (uth_parent) { - if (uth_parent->uu_flag & UT_SAS_OLDMASK) + if (uth_parent->uu_flag & UT_SAS_OLDMASK) { uth->uu_sigmask = uth_parent->uu_oldmask; - else + } else { uth->uu_sigmask = uth_parent->uu_sigmask; + } } uth->uu_context.vc_thread = thread; /* @@ -1616,7 +1610,7 @@ uthread_alloc(task_t task, thread_t thread, int noinherit) #endif } - return (ut); + return ut; } /* @@ -1645,7 +1639,7 @@ uthread_cleanup_name(void *uthread) return; } -/* +/* * This routine frees all the BSD context in uthread except the credential. * It does not free the uthread structure as well */ @@ -1701,8 +1695,9 @@ uthread_cleanup(task_t task, void *uthread, void * bsd_info) } if (uth->uu_wqset) { - if (waitq_set_is_valid(uth->uu_wqset)) + if (waitq_set_is_valid(uth->uu_wqset)) { waitq_set_deinit(uth->uu_wqset); + } FREE(uth->uu_wqset, M_SELECT); uth->uu_wqset = NULL; uth->uu_wqstate_sz = 0; @@ -1711,8 +1706,7 @@ uthread_cleanup(task_t task, void *uthread, void * bsd_info) os_reason_free(uth->uu_exit_reason); if ((task != kernel_task) && p) { - - if (((uth->uu_flag & UT_VFORK) == UT_VFORK) && (uth->uu_proc != PROC_NULL)) { + if (((uth->uu_flag & UT_VFORK) == UT_VFORK) && (uth->uu_proc != PROC_NULL)) { vfork_exit_internal(uth->uu_proc, 0, 1); } /*