X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/0a7de7458d150b5d4dffc935ba399be265ef0a1a..a991bd8d3e7fe02dbca0644054bab73c5b75324a:/bsd/kern/kern_prot.c?ds=inline diff --git a/bsd/kern/kern_prot.c b/bsd/kern/kern_prot.c index 7840d8a4b..d689b70d5 100644 --- a/bsd/kern/kern_prot.c +++ b/bsd/kern/kern_prot.c @@ -501,6 +501,27 @@ getwgroups(__unused proc_t p, __unused struct getwgroups_args *uap, __unused int return ENOTSUP; } +/* + * setsid_internal + * + * Description: Core implementation of setsid(). + */ +int +setsid_internal(proc_t p) +{ + struct pgrp * pg = PGRP_NULL; + + if (p->p_pgrpid == p->p_pid || (pg = pgfind(p->p_pid)) || p->p_lflag & P_LINVFORK) { + if (pg != PGRP_NULL) { + pg_rele(pg); + } + return EPERM; + } else { + /* enter pgrp works with its own pgrp refcount */ + (void)enterpgrp(p, p->p_pid, 1); + return 0; + } +} /* * setsid @@ -529,19 +550,11 @@ getwgroups(__unused proc_t p, __unused struct getwgroups_args *uap, __unused int int setsid(proc_t p, __unused struct setsid_args *uap, int32_t *retval) { - struct pgrp * pg = PGRP_NULL; - - if (p->p_pgrpid == p->p_pid || (pg = pgfind(p->p_pid)) || p->p_lflag & P_LINVFORK) { - if (pg != PGRP_NULL) { - pg_rele(pg); - } - return EPERM; - } else { - /* enter pgrp works with its own pgrp refcount */ - (void)enterpgrp(p, p->p_pid, 1); + int rc = setsid_internal(p); + if (rc == 0) { *retval = p->p_pid; - return 0; } + return rc; } @@ -1640,30 +1653,34 @@ settid_with_pid(proc_t p, struct settid_with_pid_args *uap, __unused int32_t *re * flag the process as having set privilege since the last exec. */ static int -setgroups1(proc_t p, u_int gidsetsize, user_addr_t gidset, uid_t gmuid, __unused int32_t *retval) +setgroups1(proc_t p, u_int ngrp, user_addr_t gidset, uid_t gmuid, __unused int32_t *retval) { - u_int ngrp; gid_t newgroups[NGROUPS] = { 0 }; int error; - kauth_cred_t my_cred, my_new_cred; - struct uthread *uthread = get_bsdthread_info(current_thread()); - DEBUG_CRED_ENTER("setgroups1 (%d/%d): %d 0x%016x %d\n", p->p_pid, (p->p_pptr ? p->p_pptr->p_pid : 0), gidsetsize, gidset, gmuid); + DEBUG_CRED_ENTER("setgroups1 (%d/%d): %d 0x%016x %d\n", p->p_pid, + (p->p_pptr ? p->p_pptr->p_pid : 0), ngrp, gidset, gmuid); - ngrp = gidsetsize; if (ngrp > NGROUPS) { return EINVAL; } - if (ngrp < 1) { - ngrp = 1; - } else { + if (ngrp >= 1) { error = copyin(gidset, (caddr_t)newgroups, ngrp * sizeof(gid_t)); if (error) { return error; } } + return setgroups_internal(p, ngrp, newgroups, gmuid); +} + +int +setgroups_internal(proc_t p, u_int ngrp, gid_t *newgroups, uid_t gmuid) +{ + struct uthread *uthread = get_bsdthread_info(current_thread()); + kauth_cred_t my_cred, my_new_cred; + int error; my_cred = kauth_cred_proc_ref(p); if ((error = suser(my_cred, &p->p_acflag))) { @@ -1671,6 +1688,11 @@ setgroups1(proc_t p, u_int gidsetsize, user_addr_t gidset, uid_t gmuid, __unused return error; } + if (ngrp < 1) { + ngrp = 1; + newgroups[0] = 0; + } + if ((uthread->uu_flag & UT_SETUID) != 0) { #if DEBUG_CRED int my_cred_flags = uthread->uu_ucred->cr_flags; @@ -1942,6 +1964,18 @@ getlogin(proc_t p, struct getlogin_args *uap, __unused int32_t *retval) return copyout((caddr_t)buffer, uap->namebuf, uap->namelen); } +void +setlogin_internal(proc_t p, const char login[static MAXLOGNAME]) +{ + struct session *sessp = proc_session(p); + + if (sessp != SESSION_NULL) { + session_lock(sessp); + bcopy(login, sessp->s_login, MAXLOGNAME); + session_unlock(sessp); + session_rele(sessp); + } +} /* * setlogin @@ -1965,7 +1999,6 @@ setlogin(proc_t p, struct setlogin_args *uap, __unused int32_t *retval) int error; size_t dummy = 0; char buffer[MAXLOGNAME + 1]; - struct session * sessp; if ((error = proc_suser(p))) { return error; @@ -1978,15 +2011,7 @@ setlogin(proc_t p, struct setlogin_args *uap, __unused int32_t *retval) (caddr_t) &buffer[0], MAXLOGNAME - 1, (size_t *)&dummy); - sessp = proc_session(p); - - if (sessp != SESSION_NULL) { - session_lock(sessp); - bcopy(buffer, sessp->s_login, MAXLOGNAME); - session_unlock(sessp); - session_rele(sessp); - } - + setlogin_internal(p, buffer); if (!error) { AUDIT_ARG(text, buffer); @@ -2008,6 +2033,30 @@ set_security_token(proc_t p) return set_security_token_task_internal(p, p->task); } +static void +proc_calc_audit_token(proc_t p, kauth_cred_t my_cred, audit_token_t *audit_token) +{ + posix_cred_t my_pcred = posix_cred_get(my_cred); + + /* + * The current layout of the Mach audit token explicitly + * adds these fields. But nobody should rely on such + * a literal representation. Instead, the BSM library + * provides a function to convert an audit token into + * a BSM subject. Use of that mechanism will isolate + * the user of the trailer from future representation + * changes. + */ + audit_token->val[0] = my_cred->cr_audit.as_aia_p->ai_auid; + audit_token->val[1] = my_pcred->cr_uid; + audit_token->val[2] = my_pcred->cr_gid; + audit_token->val[3] = my_pcred->cr_ruid; + audit_token->val[4] = my_pcred->cr_rgid; + audit_token->val[5] = p->p_pid; + audit_token->val[6] = my_cred->cr_audit.as_aia_p->ai_asid; + audit_token->val[7] = p->p_idversion; +} + /* * 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 @@ -2017,10 +2066,9 @@ set_security_token(proc_t p) int set_security_token_task_internal(proc_t p, void *t) { + kauth_cred_t my_cred; 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; @@ -2039,7 +2087,8 @@ set_security_token_task_internal(proc_t p, void *t) } my_cred = kauth_cred_proc_ref(p); - my_pcred = posix_cred_get(my_cred); + + proc_calc_audit_token(p, my_cred, &audit_token); /* XXX mach_init doesn't have a p_ucred when it calls this function */ if (IS_VALID_CRED(my_cred)) { @@ -2050,24 +2099,6 @@ set_security_token_task_internal(proc_t p, void *t) sec_token.val[1] = 0; } - /* - * The current layout of the Mach audit token explicitly - * adds these fields. But nobody should rely on such - * a literal representation. Instead, the BSM library - * provides a function to convert an audit token into - * a BSM subject. Use of that mechanism will isolate - * the user of the trailer from future representation - * changes. - */ - audit_token.val[0] = my_cred->cr_audit.as_aia_p->ai_auid; - audit_token.val[1] = my_pcred->cr_uid; - audit_token.val[2] = my_pcred->cr_gid; - audit_token.val[3] = my_pcred->cr_ruid; - audit_token.val[4] = my_pcred->cr_rgid; - audit_token.val[5] = p->p_pid; - audit_token.val[6] = my_cred->cr_audit.as_aia_p->ai_asid; - audit_token.val[7] = p->p_idversion; - host_priv = (sec_token.val[0]) ? HOST_PRIV_NULL : host_priv_self(); #if CONFIG_MACF if (host_priv != HOST_PRIV_NULL && mac_system_check_host_priv(my_cred)) { @@ -2090,6 +2121,22 @@ set_security_token_task_internal(proc_t p, void *t) host_priv) != KERN_SUCCESS; } +void +proc_parent_audit_token(proc_t p, audit_token_t *token_out) +{ + proc_t parent; + kauth_cred_t my_cred; + + proc_list_lock(); + + parent = p->p_pptr; + my_cred = kauth_cred_proc_ref(parent); + proc_calc_audit_token(parent, my_cred, token_out); + kauth_cred_unref(&my_cred); + + proc_list_unlock(); +} + int get_audit_token_pid(audit_token_t *audit_token);