X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/3e170ce000f1506b7b5d2c5c7faec85ceabb573d..e8c3f78193f1895ea514044358b93b1add9322f3:/bsd/kern/kern_prot.c diff --git a/bsd/kern/kern_prot.c b/bsd/kern/kern_prot.c index 5df82a23f..36beb2737 100644 --- a/bsd/kern/kern_prot.c +++ b/bsd/kern/kern_prot.c @@ -95,8 +95,7 @@ #include #include #include - -#define chgproccnt_ok(p) 1 +#include #include @@ -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 */ @@ -670,6 +669,12 @@ out: * real, effective, or saved user or group IDs since beginning * execution. */ +int +proc_issetugid (proc_t p) +{ + return (p->p_flag & P_SUGID) ? 1 : 0; +} + int issetugid(proc_t p, __unused struct issetugid_args *uap, int32_t *retval) { @@ -682,7 +687,7 @@ issetugid(proc_t p, __unused struct issetugid_args *uap, int32_t *retval) * that libc *might* have put in their data segment. */ - *retval = (p->p_flag & P_SUGID) ? 1 : 0; + *retval = proc_issetugid(p); return (0); } @@ -778,11 +783,11 @@ 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); } - proc_lock(p); + proc_ucred_lock(p); /* * We need to protect for a race where another thread * also changed the credential after we took our @@ -792,12 +797,12 @@ setuid(proc_t p, struct setuid_args *uap, __unused int32_t *retval) * Note: the kauth_cred_setresuid has consumed a reference to my_cred, it p_ucred != my_cred, then my_cred must not be dereferenced! */ if (p->p_ucred != my_cred) { - proc_unlock(p); + proc_ucred_unlock(p); /* * 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); @@ -811,12 +816,12 @@ setuid(proc_t p, struct setuid_args *uap, __unused int32_t *retval) PROC_UPDATE_CREDS_ONPROC(p); OSBitOrAtomic(P_SUGID, &p->p_flag); - proc_unlock(p); + proc_ucred_unlock(p); /* * 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); } } @@ -885,7 +890,7 @@ seteuid(proc_t p, struct seteuid_args *uap, __unused int32_t *retval) DEBUG_CRED_CHANGE("seteuid CH(%d): %p/0x%08x -> %p/0x%08x\n", p->p_pid, my_cred, my_pcred->cr_flags, my_new_cred, posix_cred_get(my_new_cred)->cr_flags); - proc_lock(p); + proc_ucred_lock(p); /* * We need to protect for a race where another thread * also changed the credential after we took our @@ -893,7 +898,7 @@ seteuid(proc_t p, struct seteuid_args *uap, __unused int32_t *retval) * should restart this again with the new cred. */ if (p->p_ucred != my_cred) { - proc_unlock(p); + proc_ucred_unlock(p); kauth_cred_unref(&my_new_cred); my_cred = kauth_cred_proc_ref(p); my_pcred = posix_cred_get(my_cred); @@ -904,7 +909,7 @@ seteuid(proc_t p, struct seteuid_args *uap, __unused int32_t *retval) /* update cred on proc */ PROC_UPDATE_CREDS_ONPROC(p); OSBitOrAtomic(P_SUGID, &p->p_flag); - proc_unlock(p); + proc_ucred_unlock(p); } break; } @@ -1026,11 +1031,11 @@ 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); } - proc_lock(p); + proc_ucred_lock(p); /* * We need to protect for a race where another thread * also changed the credential after we took our @@ -1040,8 +1045,8 @@ setreuid(proc_t p, struct setreuid_args *uap, __unused int32_t *retval) * Note: the kauth_cred_setresuid has consumed a reference to my_cred, it p_ucred != my_cred, then my_cred must not be dereferenced! */ if (p->p_ucred != my_cred) { - proc_unlock(p); - if (ruid != KAUTH_UID_NONE && chgproccnt_ok(p)) { + proc_ucred_unlock(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. @@ -1059,9 +1064,9 @@ setreuid(proc_t p, struct setreuid_args *uap, __unused int32_t *retval) /* update cred on proc */ PROC_UPDATE_CREDS_ONPROC(p); OSBitOrAtomic(P_SUGID, &p->p_flag); - proc_unlock(p); + 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 @@ -1155,7 +1160,7 @@ setgid(proc_t p, struct setgid_args *uap, __unused int32_t *retval) DEBUG_CRED_CHANGE("setgid(CH)%d: %p/0x%08x->%p/0x%08x\n", p->p_pid, my_cred, my_cred->cr_flags, my_new_cred, my_new_cred->cr_flags); - proc_lock(p); + proc_ucred_lock(p); /* * We need to protect for a race where another thread * also changed the credential after we took our @@ -1163,7 +1168,7 @@ setgid(proc_t p, struct setgid_args *uap, __unused int32_t *retval) * should restart this again with the new cred. */ if (p->p_ucred != my_cred) { - proc_unlock(p); + proc_ucred_unlock(p); kauth_cred_unref(&my_new_cred); /* try again */ my_cred = kauth_cred_proc_ref(p); @@ -1174,7 +1179,7 @@ setgid(proc_t p, struct setgid_args *uap, __unused int32_t *retval) /* update cred on proc */ PROC_UPDATE_CREDS_ONPROC(p); OSBitOrAtomic(P_SUGID, &p->p_flag); - proc_unlock(p); + proc_ucred_unlock(p); } break; } @@ -1246,7 +1251,7 @@ setegid(proc_t p, struct setegid_args *uap, __unused int32_t *retval) DEBUG_CRED_CHANGE("setegid(CH)%d: %p/0x%08x->%p/0x%08x\n", p->p_pid, my_cred, my_pcred->cr_flags, my_new_cred, posix_cred_get(my_new_cred)->cr_flags); - proc_lock(p); + proc_ucred_lock(p); /* * We need to protect for a race where another thread * also changed the credential after we took our @@ -1254,7 +1259,7 @@ setegid(proc_t p, struct setegid_args *uap, __unused int32_t *retval) * should restart this again with the new cred. */ if (p->p_ucred != my_cred) { - proc_unlock(p); + proc_ucred_unlock(p); kauth_cred_unref(&my_new_cred); /* try again */ my_cred = kauth_cred_proc_ref(p); @@ -1265,7 +1270,7 @@ setegid(proc_t p, struct setegid_args *uap, __unused int32_t *retval) /* update cred on proc */ PROC_UPDATE_CREDS_ONPROC(p); OSBitOrAtomic(P_SUGID, &p->p_flag); - proc_unlock(p); + proc_ucred_unlock(p); } break; } @@ -1393,14 +1398,14 @@ setregid(proc_t p, struct setregid_args *uap, __unused int32_t *retval) DEBUG_CRED_CHANGE("setregid(CH)%d: %p/0x%08x->%p/0x%08x\n", p->p_pid, my_cred, my_pcred->cr_flags, my_new_cred, posix_cred_get(my_new_cred)->cr_flags); - proc_lock(p); + proc_ucred_lock(p); /* need to protect for a race where another thread * also changed the credential after we took our * reference. If p_ucred has changed then we * should restart this again with the new cred. */ if (p->p_ucred != my_cred) { - proc_unlock(p); + proc_ucred_unlock(p); kauth_cred_unref(&my_new_cred); /* try again */ my_cred = kauth_cred_proc_ref(p); @@ -1411,7 +1416,7 @@ setregid(proc_t p, struct setregid_args *uap, __unused int32_t *retval) /* update cred on proc */ PROC_UPDATE_CREDS_ONPROC(p); OSBitOrAtomic(P_SUGID, &p->p_flag); /* XXX redundant? */ - proc_unlock(p); + proc_ucred_unlock(p); } break; } @@ -1698,7 +1703,7 @@ setgroups1(proc_t p, u_int gidsetsize, user_addr_t gidset, uid_t gmuid, __unused DEBUG_CRED_CHANGE("setgroups1(CH)%d: %p/0x%08x->%p/0x%08x\n", p->p_pid, my_cred, my_cred->cr_flags, my_new_cred, my_new_cred->cr_flags); - proc_lock(p); + proc_ucred_lock(p); /* * We need to protect for a race where another * thread also changed the credential after we @@ -1707,7 +1712,7 @@ setgroups1(proc_t p, u_int gidsetsize, user_addr_t gidset, uid_t gmuid, __unused * with the new cred. */ if (p->p_ucred != my_cred) { - proc_unlock(p); + proc_ucred_unlock(p); kauth_cred_unref(&my_new_cred); my_cred = kauth_cred_proc_ref(p); /* try again */ @@ -1717,7 +1722,7 @@ setgroups1(proc_t p, u_int gidsetsize, user_addr_t gidset, uid_t gmuid, __unused /* update cred on proc */ PROC_UPDATE_CREDS_ONPROC(p); OSBitOrAtomic(P_SUGID, &p->p_flag); - proc_unlock(p); + proc_ucred_unlock(p); } break; } @@ -1985,12 +1990,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 +2016,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 +2064,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);