X-Git-Url: https://git.saurik.com/apple/xnu.git/blobdiff_plain/593a1d5fd87cdf5b46dd5fcb84467b432cea0f91..15129b1c8dbb3650c63b70adb1cad9af601c6c17:/bsd/kern/kern_prot.c diff --git a/bsd/kern/kern_prot.c b/bsd/kern/kern_prot.c index 46ab8bf1b..73806d055 100644 --- a/bsd/kern/kern_prot.c +++ b/bsd/kern/kern_prot.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2000-2007 Apple Inc. All rights reserved. + * Copyright (c) 2000-2008 Apple Inc. All rights reserved. * * @APPLE_OSREFERENCE_LICENSE_HEADER_START@ * @@ -24,9 +24,11 @@ * limitations under the License. * * @APPLE_OSREFERENCE_LICENSE_HEADER_END@ - */ -/* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */ -/* + * + * + * Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved + * + * * Copyright (c) 1982, 1986, 1989, 1990, 1991, 1993 * The Regents of the University of California. All rights reserved. * (c) UNIX System Laboratories, Inc. @@ -64,18 +66,19 @@ * SUCH DAMAGE. * * @(#)kern_prot.c 8.9 (Berkeley) 2/14/95 - */ -/* + * + * * NOTICE: This file was modified by McAfee Research in 2004 to introduce * support for mandatory and extensible security protections. This notice * is included in support of clause 2.2 (b) of the Apple Public License, * Version 2.0. - */ -/* + * + * * NOTICE: This file was modified by SPARTA, Inc. in 2005 to introduce * support for mandatory and extensible security protections. This notice * is included in support of clause 2.2 (b) of the Apple Public License, * Version 2.0. + * */ /* @@ -93,7 +96,7 @@ #include #include -#include +#include #if CONFIG_LCTX #include @@ -116,8 +119,6 @@ #include -int groupmember(gid_t gid, kauth_cred_t cred); - /* * Credential debugging; we can track entry into a function that might * change a credential, and we can track actual credential changes that @@ -152,9 +153,9 @@ extern void kauth_cred_print(kauth_cred_t cred); * XXX: Belongs in kern_proc.c */ int -setprivexec(proc_t p, struct setprivexec_args *uap, register_t *retval) +setprivexec(proc_t p, struct setprivexec_args *uap, int32_t *retval) { - AUDIT_ARG(value, uap->flag); + AUDIT_ARG(value32, uap->flag); *retval = p->p_debugger; p->p_debugger = (uap->flag != 0); return(0); @@ -173,7 +174,7 @@ setprivexec(proc_t p, struct setprivexec_args *uap, register_t *retval) * XXX: Belongs in kern_proc.c */ int -getpid(proc_t p, __unused struct getpid_args *uap, register_t *retval) +getpid(proc_t p, __unused struct getpid_args *uap, int32_t *retval) { *retval = p->p_pid; @@ -193,7 +194,7 @@ getpid(proc_t p, __unused struct getpid_args *uap, register_t *retval) * XXX: Belongs in kern_proc.c */ int -getppid(proc_t p, __unused struct getppid_args *uap, register_t *retval) +getppid(proc_t p, __unused struct getppid_args *uap, int32_t *retval) { *retval = p->p_ppid; @@ -213,7 +214,7 @@ getppid(proc_t p, __unused struct getppid_args *uap, register_t *retval) * XXX: Belongs in kern_proc.c */ int -getpgrp(proc_t p, __unused struct getpgrp_args *uap, register_t *retval) +getpgrp(proc_t p, __unused struct getpgrp_args *uap, int32_t *retval) { *retval = p->p_pgrpid; @@ -238,7 +239,7 @@ getpgrp(proc_t p, __unused struct getpgrp_args *uap, register_t *retval) * XXX: Belongs in kern_proc.c */ int -getpgid(proc_t p, struct getpgid_args *uap, register_t *retval) +getpgid(proc_t p, struct getpgid_args *uap, int32_t *retval) { proc_t pt; int refheld = 0; @@ -275,7 +276,7 @@ found: * XXX: Belongs in kern_proc.c */ int -getsid(proc_t p, struct getsid_args *uap, register_t *retval) +getsid(proc_t p, struct getsid_args *uap, int32_t *retval) { proc_t pt; int refheld = 0; @@ -309,7 +310,7 @@ found: * Returns: uid_t The real uid of the caller */ int -getuid(__unused proc_t p, __unused struct getuid_args *uap, register_t *retval) +getuid(__unused proc_t p, __unused struct getuid_args *uap, int32_t *retval) { *retval = kauth_getruid(); @@ -327,7 +328,7 @@ getuid(__unused proc_t p, __unused struct getuid_args *uap, register_t *retval) * Returns: uid_t The effective uid of the caller */ int -geteuid(__unused proc_t p, __unused struct geteuid_args *uap, register_t *retval) +geteuid(__unused proc_t p, __unused struct geteuid_args *uap, int32_t *retval) { *retval = kauth_getuid(); @@ -347,7 +348,7 @@ geteuid(__unused proc_t p, __unused struct geteuid_args *uap, register_t *retval * ESRCH No per thread identity active */ int -gettid(__unused proc_t p, struct gettid_args *uap, register_t *retval) +gettid(__unused proc_t p, struct gettid_args *uap, int32_t *retval) { struct uthread *uthread = get_bsdthread_info(current_thread()); int error; @@ -359,9 +360,9 @@ gettid(__unused proc_t p, struct gettid_args *uap, register_t *retval) if (!(uthread->uu_flag & UT_SETUID)) return (ESRCH); - if ((error = suword(uap->uidp, uthread->uu_ucred->cr_ruid))) + if ((error = suword(uap->uidp, kauth_cred_getruid(uthread->uu_ucred)))) return (error); - if ((error = suword(uap->gidp, uthread->uu_ucred->cr_rgid))) + if ((error = suword(uap->gidp, kauth_cred_getrgid(uthread->uu_ucred)))) return (error); *retval = 0; @@ -379,7 +380,7 @@ gettid(__unused proc_t p, struct gettid_args *uap, register_t *retval) * Returns: gid_t The real gid of the caller */ int -getgid(__unused proc_t p, __unused struct getgid_args *uap, register_t *retval) +getgid(__unused proc_t p, __unused struct getgid_args *uap, int32_t *retval) { *retval = kauth_getrgid(); @@ -403,7 +404,7 @@ getgid(__unused proc_t p, __unused struct getgid_args *uap, register_t *retval) * detail. */ int -getegid(__unused proc_t p, __unused struct getegid_args *uap, register_t *retval) +getegid(__unused proc_t p, __unused struct getegid_args *uap, int32_t *retval) { *retval = kauth_getgid(); @@ -442,26 +443,28 @@ getegid(__unused proc_t p, __unused struct getegid_args *uap, register_t *retval * be returned by this call. */ int -getgroups(__unused proc_t p, struct getgroups_args *uap, register_t *retval) +getgroups(__unused proc_t p, struct getgroups_args *uap, int32_t *retval) { int ngrp; int error; kauth_cred_t cred; + posix_cred_t pcred; /* grab reference while we muck around with the credential */ cred = kauth_cred_get_with_ref(); + pcred = posix_cred_get(cred); if ((ngrp = uap->gidsetsize) == 0) { - *retval = cred->cr_ngroups; + *retval = pcred->cr_ngroups; kauth_cred_unref(&cred); return (0); } - if (ngrp < cred->cr_ngroups) { + if (ngrp < pcred->cr_ngroups) { kauth_cred_unref(&cred); return (EINVAL); } - ngrp = cred->cr_ngroups; - if ((error = copyout((caddr_t)cred->cr_groups, + ngrp = pcred->cr_ngroups; + if ((error = copyout((caddr_t)pcred->cr_groups, uap->gidset, ngrp * sizeof(gid_t)))) { kauth_cred_unref(&cred); @@ -475,23 +478,27 @@ getgroups(__unused proc_t p, struct getgroups_args *uap, register_t *retval) /* * Return the per-thread/per-process supplementary groups list. + * + * XXX implement getsgroups + * */ -#warning XXX implement getsgroups + int -getsgroups(__unused proc_t p, __unused struct getsgroups_args *uap, __unused register_t *retval) +getsgroups(__unused proc_t p, __unused struct getsgroups_args *uap, __unused int32_t *retval) { - /* XXX implement */ return(ENOTSUP); } /* * Return the per-thread/per-process whiteout groups list. + * + * XXX implement getwgroups + * */ -#warning XXX implement getwgroups + int -getwgroups(__unused proc_t p, __unused struct getwgroups_args *uap, __unused register_t *retval) +getwgroups(__unused proc_t p, __unused struct getwgroups_args *uap, __unused int32_t *retval) { - /* XXX implement */ return(ENOTSUP); } @@ -521,7 +528,7 @@ getwgroups(__unused proc_t p, __unused struct getwgroups_args *uap, __unused reg * XXX: Belongs in kern_proc.c */ int -setsid(proc_t p, __unused struct setsid_args *uap, register_t *retval) +setsid(proc_t p, __unused struct setsid_args *uap, int32_t *retval) { struct pgrp * pg = PGRP_NULL; @@ -576,7 +583,7 @@ setsid(proc_t p, __unused struct setsid_args *uap, register_t *retval) * XXX: Belongs in kern_proc.c */ int -setpgid(proc_t curp, register struct setpgid_args *uap, __unused register_t *retval) +setpgid(proc_t curp, register struct setpgid_args *uap, __unused int32_t *retval) { proc_t targp = PROC_NULL; /* target process */ struct pgrp *pg = PGRP_NULL; /* target pgrp */ @@ -666,7 +673,7 @@ out: * execution. */ int -issetugid(proc_t p, __unused struct issetugid_args *uap, register_t *retval) +issetugid(proc_t p, __unused struct issetugid_args *uap, int32_t *retval) { /* * Note: OpenBSD sets a P_SUGIDEXEC flag set at execve() time, @@ -703,7 +710,7 @@ issetugid(proc_t p, __unused struct issetugid_args *uap, register_t *retval) * flag the process as having set privilege since the last exec. */ int -setuid(proc_t p, struct setuid_args *uap, __unused register_t *retval) +setuid(proc_t p, struct setuid_args *uap, __unused int32_t *retval) { uid_t uid; uid_t svuid = KAUTH_UID_NONE; @@ -711,17 +718,19 @@ setuid(proc_t p, struct setuid_args *uap, __unused register_t *retval) uid_t gmuid = KAUTH_UID_NONE; int error; kauth_cred_t my_cred, my_new_cred; + posix_cred_t my_pcred; uid = uap->uid; my_cred = kauth_cred_proc_ref(p); + my_pcred = posix_cred_get(my_cred); DEBUG_CRED_ENTER("setuid (%d/%d): %p %d\n", p->p_pid, (p->p_pptr ? p->p_pptr->p_pid : 0), my_cred, uap->uid); - AUDIT_ARG(uid, uid, 0, 0, 0); + AUDIT_ARG(uid, uid); - if (uid != my_cred->cr_ruid && /* allow setuid(getuid()) */ - uid != my_cred->cr_svuid && /* allow setuid(saved uid) */ + if (uid != my_pcred->cr_ruid && /* allow setuid(getuid()) */ + uid != my_pcred->cr_svuid && /* allow setuid(saved uid) */ (error = suser(my_cred, &p->p_acflag))) { kauth_cred_unref(&my_cred); return (error); @@ -742,7 +751,7 @@ setuid(proc_t p, struct setuid_args *uap, __unused register_t *retval) * chgproccnt uses list lock for protection */ (void)chgproccnt(uid, 1); - (void)chgproccnt(kauth_getruid(), -1); + (void)chgproccnt(my_pcred->cr_ruid, -1); } /* get current credential and take a reference while we muck with it */ @@ -756,7 +765,7 @@ setuid(proc_t p, struct setuid_args *uap, __unused register_t *retval) * to something other than the default list for the user, as * in entering a group or leaving an exclusion group). */ - if (!(my_cred->cr_flags & CRF_NOMEMBERD)) + if (!(my_pcred->cr_flags & CRF_NOMEMBERD)) gmuid = uid; /* @@ -769,7 +778,7 @@ setuid(proc_t p, struct setuid_args *uap, __unused register_t *retval) my_new_cred = kauth_cred_setresuid(my_cred, ruid, uid, svuid, gmuid); if (my_cred != my_new_cred) { - DEBUG_CRED_CHANGE("setuid 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); + DEBUG_CRED_CHANGE("setuid 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); /* @@ -786,7 +795,10 @@ setuid(proc_t p, struct setuid_args *uap, __unused register_t *retval) continue; } p->p_ucred = my_new_cred; - OSBitOrAtomic(P_SUGID, (UInt32 *)&p->p_flag); + /* update cred on proc */ + PROC_UPDATE_CREDS_ONPROC(p); + + OSBitOrAtomic(P_SUGID, &p->p_flag); proc_unlock(p); } break; @@ -818,20 +830,22 @@ setuid(proc_t p, struct setuid_args *uap, __unused register_t *retval) * flag the process as having set privilege since the last exec. */ int -seteuid(proc_t p, struct seteuid_args *uap, __unused register_t *retval) +seteuid(proc_t p, struct seteuid_args *uap, __unused int32_t *retval) { uid_t euid; int error; kauth_cred_t my_cred, my_new_cred; + posix_cred_t my_pcred; DEBUG_CRED_ENTER("seteuid: %d\n", uap->euid); euid = uap->euid; - AUDIT_ARG(uid, 0, euid, 0, 0); + AUDIT_ARG(euid, euid); my_cred = kauth_cred_proc_ref(p); + my_pcred = posix_cred_get(my_cred); - if (euid != my_cred->cr_ruid && euid != my_cred->cr_svuid && + if (euid != my_pcred->cr_ruid && euid != my_pcred->cr_svuid && (error = suser(my_cred, &p->p_acflag))) { kauth_cred_unref(&my_cred); return (error); @@ -850,11 +864,11 @@ seteuid(proc_t p, struct seteuid_args *uap, __unused register_t *retval) * passed in. The subsequent compare is safe, because it is * a pointer compare rather than a contents compare. */ - my_new_cred = kauth_cred_setresuid(my_cred, KAUTH_UID_NONE, euid, KAUTH_UID_NONE, my_cred->cr_gmuid); + my_new_cred = kauth_cred_setresuid(my_cred, KAUTH_UID_NONE, euid, KAUTH_UID_NONE, my_pcred->cr_gmuid); if (my_cred != my_new_cred) { - DEBUG_CRED_CHANGE("seteuid 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); + 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); /* @@ -871,7 +885,9 @@ seteuid(proc_t p, struct seteuid_args *uap, __unused register_t *retval) continue; } p->p_ucred = my_new_cred; - OSBitOrAtomic(P_SUGID, (UInt32 *)&p->p_flag); + /* update cred on proc */ + PROC_UPDATE_CREDS_ONPROC(p); + OSBitOrAtomic(P_SUGID, &p->p_flag); proc_unlock(p); } break; @@ -916,11 +932,12 @@ seteuid(proc_t p, struct seteuid_args *uap, __unused register_t *retval) * flag the process as having set privilege since the last exec. */ int -setreuid(proc_t p, struct setreuid_args *uap, __unused register_t *retval) +setreuid(proc_t p, struct setreuid_args *uap, __unused int32_t *retval) { uid_t ruid, euid; int error; kauth_cred_t my_cred, my_new_cred; + posix_cred_t my_pcred; DEBUG_CRED_ENTER("setreuid %d %d\n", uap->ruid, uap->euid); @@ -930,18 +947,20 @@ setreuid(proc_t p, struct setreuid_args *uap, __unused register_t *retval) ruid = KAUTH_UID_NONE; if (euid == (uid_t)-1) euid = KAUTH_UID_NONE; - AUDIT_ARG(uid, euid, ruid, 0, 0); + AUDIT_ARG(euid, euid); + AUDIT_ARG(ruid, ruid); my_cred = kauth_cred_proc_ref(p); + my_pcred = posix_cred_get(my_cred); if (((ruid != KAUTH_UID_NONE && /* allow no change of ruid */ - ruid != my_cred->cr_ruid && /* allow ruid = ruid */ - ruid != my_cred->cr_uid && /* allow ruid = euid */ - ruid != my_cred->cr_svuid) || /* allow ruid = svuid */ + ruid != my_pcred->cr_ruid && /* allow ruid = ruid */ + ruid != my_pcred->cr_uid && /* allow ruid = euid */ + ruid != my_pcred->cr_svuid) || /* allow ruid = svuid */ (euid != KAUTH_UID_NONE && /* allow no change of euid */ - euid != my_cred->cr_uid && /* allow euid = euid */ - euid != my_cred->cr_ruid && /* allow euid = ruid */ - euid != my_cred->cr_svuid)) && /* allow euid = svui */ + euid != my_pcred->cr_uid && /* allow euid = euid */ + euid != my_pcred->cr_ruid && /* allow euid = ruid */ + euid != my_pcred->cr_svuid)) && /* allow euid = svui */ (error = suser(my_cred, &p->p_acflag))) { /* allow root user any */ kauth_cred_unref(&my_cred); return (error); @@ -957,8 +976,8 @@ setreuid(proc_t p, struct setreuid_args *uap, __unused register_t *retval) uid_t new_ruid; uid_t svuid = KAUTH_UID_NONE; - new_euid = my_cred->cr_uid; - new_ruid = my_cred->cr_ruid; + new_euid = my_pcred->cr_uid; + new_ruid = my_pcred->cr_ruid; /* * Set the credential with new info. If there is no change, @@ -967,18 +986,18 @@ setreuid(proc_t p, struct setreuid_args *uap, __unused register_t *retval) * passed in. The subsequent compare is safe, because it is * a pointer compare rather than a contents compare. */ - if (euid == KAUTH_UID_NONE && my_cred->cr_uid != euid) { + if (euid == KAUTH_UID_NONE && my_pcred->cr_uid != euid) { /* changing the effective UID */ new_euid = euid; - OSBitOrAtomic(P_SUGID, (UInt32 *)&p->p_flag); + OSBitOrAtomic(P_SUGID, &p->p_flag); } - if (ruid != KAUTH_UID_NONE && my_cred->cr_ruid != ruid) { + if (ruid != KAUTH_UID_NONE && my_pcred->cr_ruid != ruid) { /* changing the real UID; must do user accounting */ /* chgproccnt uses list lock for protection */ (void)chgproccnt(ruid, 1); - (void)chgproccnt(my_cred->cr_ruid, -1); + (void)chgproccnt(my_pcred->cr_ruid, -1); new_ruid = ruid; - OSBitOrAtomic(P_SUGID, (UInt32 *)&p->p_flag); + OSBitOrAtomic(P_SUGID, &p->p_flag); } /* * If the newly requested real uid or effective uid does @@ -986,17 +1005,17 @@ setreuid(proc_t p, struct setreuid_args *uap, __unused register_t *retval) * new effective uid. We are protected from escalation * by the prechecking. */ - if (my_cred->cr_svuid != uap->ruid && - my_cred->cr_svuid != uap->euid) { + if (my_pcred->cr_svuid != uap->ruid && + my_pcred->cr_svuid != uap->euid) { svuid = new_euid; - OSBitOrAtomic(P_SUGID, (UInt32 *)&p->p_flag); + OSBitOrAtomic(P_SUGID, &p->p_flag); } - my_new_cred = kauth_cred_setresuid(my_cred, ruid, euid, svuid, my_cred->cr_gmuid); + my_new_cred = kauth_cred_setresuid(my_cred, ruid, euid, svuid, my_pcred->cr_gmuid); if (my_cred != my_new_cred) { - DEBUG_CRED_CHANGE("setreuid 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); + DEBUG_CRED_CHANGE("setreuid 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); /* @@ -1013,7 +1032,9 @@ setreuid(proc_t p, struct setreuid_args *uap, __unused register_t *retval) continue; } p->p_ucred = my_new_cred; - OSBitOrAtomic(P_SUGID, (UInt32 *)&p->p_flag); /* XXX redundant? */ + /* update cred on proc */ + PROC_UPDATE_CREDS_ONPROC(p); + OSBitOrAtomic(P_SUGID, &p->p_flag); /* XXX redundant? */ proc_unlock(p); } break; @@ -1052,23 +1073,25 @@ setreuid(proc_t p, struct setreuid_args *uap, __unused register_t *retval) * the supplementary group list unchanged. */ int -setgid(proc_t p, struct setgid_args *uap, __unused register_t *retval) +setgid(proc_t p, struct setgid_args *uap, __unused int32_t *retval) { gid_t gid; gid_t rgid = KAUTH_GID_NONE; gid_t svgid = KAUTH_GID_NONE; int error; kauth_cred_t my_cred, my_new_cred; + posix_cred_t my_pcred; DEBUG_CRED_ENTER("setgid(%d/%d): %d\n", p->p_pid, (p->p_pptr ? p->p_pptr->p_pid : 0), uap->gid); gid = uap->gid; - AUDIT_ARG(gid, gid, 0, 0, 0); + AUDIT_ARG(gid, gid); my_cred = kauth_cred_proc_ref(p); + my_pcred = posix_cred_get(my_cred); - if (gid != my_cred->cr_rgid && /* allow setgid(getgid()) */ - gid != my_cred->cr_svgid && /* allow setgid(saved gid) */ + if (gid != my_pcred->cr_rgid && /* allow setgid(getgid()) */ + gid != my_pcred->cr_svgid && /* allow setgid(saved gid) */ (error = suser(my_cred, &p->p_acflag))) { kauth_cred_unref(&my_cred); return (error); @@ -1113,7 +1136,9 @@ setgid(proc_t p, struct setgid_args *uap, __unused register_t *retval) continue; } p->p_ucred = my_new_cred; - OSBitOrAtomic(P_SUGID, (UInt32 *)&p->p_flag); + /* update cred on proc */ + PROC_UPDATE_CREDS_ONPROC(p); + OSBitOrAtomic(P_SUGID, &p->p_flag); proc_unlock(p); } break; @@ -1150,21 +1175,23 @@ setgid(proc_t p, struct setgid_args *uap, __unused register_t *retval) * the supplementary group list unchanged. */ int -setegid(proc_t p, struct setegid_args *uap, __unused register_t *retval) +setegid(proc_t p, struct setegid_args *uap, __unused int32_t *retval) { gid_t egid; int error; kauth_cred_t my_cred, my_new_cred; + posix_cred_t my_pcred; DEBUG_CRED_ENTER("setegid %d\n", uap->egid); egid = uap->egid; - AUDIT_ARG(gid, 0, egid, 0, 0); + AUDIT_ARG(egid, egid); my_cred = kauth_cred_proc_ref(p); + my_pcred = posix_cred_get(my_cred); - if (egid != my_cred->cr_rgid && - egid != my_cred->cr_svgid && + if (egid != my_pcred->cr_rgid && + egid != my_pcred->cr_svgid && (error = suser(my_cred, &p->p_acflag))) { kauth_cred_unref(&my_cred); return (error); @@ -1182,7 +1209,7 @@ setegid(proc_t p, struct setegid_args *uap, __unused register_t *retval) my_new_cred = kauth_cred_setresgid(my_cred, KAUTH_GID_NONE, egid, KAUTH_GID_NONE); if (my_cred != my_new_cred) { - DEBUG_CRED_CHANGE("setegid(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); + 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); /* @@ -1199,7 +1226,9 @@ setegid(proc_t p, struct setegid_args *uap, __unused register_t *retval) continue; } p->p_ucred = my_new_cred; - OSBitOrAtomic(P_SUGID, (UInt32 *)&p->p_flag); + /* update cred on proc */ + PROC_UPDATE_CREDS_ONPROC(p); + OSBitOrAtomic(P_SUGID, &p->p_flag); proc_unlock(p); } break; @@ -1250,11 +1279,12 @@ setegid(proc_t p, struct setegid_args *uap, __unused register_t *retval) * the supplementary group list unchanged. */ int -setregid(proc_t p, struct setregid_args *uap, __unused register_t *retval) +setregid(proc_t p, struct setregid_args *uap, __unused int32_t *retval) { gid_t rgid, egid; int error; kauth_cred_t my_cred, my_new_cred; + posix_cred_t my_pcred; DEBUG_CRED_ENTER("setregid %d %d\n", uap->rgid, uap->egid); @@ -1265,19 +1295,21 @@ setregid(proc_t p, struct setregid_args *uap, __unused register_t *retval) rgid = KAUTH_GID_NONE; if (egid == (uid_t)-1) egid = KAUTH_GID_NONE; - AUDIT_ARG(gid, egid, rgid, 0, 0); + AUDIT_ARG(egid, egid); + AUDIT_ARG(rgid, rgid); my_cred = kauth_cred_proc_ref(p); + my_pcred = posix_cred_get(my_cred); if (((rgid != KAUTH_UID_NONE && /* allow no change of rgid */ - rgid != my_cred->cr_rgid && /* allow rgid = rgid */ - rgid != my_cred->cr_gid && /* allow rgid = egid */ - rgid != my_cred->cr_svgid) || /* allow rgid = svgid */ + rgid != my_pcred->cr_rgid && /* allow rgid = rgid */ + rgid != my_pcred->cr_gid && /* allow rgid = egid */ + rgid != my_pcred->cr_svgid) || /* allow rgid = svgid */ (egid != KAUTH_UID_NONE && /* allow no change of egid */ - egid != my_cred->cr_groups[0] && /* allow no change of egid */ - egid != my_cred->cr_gid && /* allow egid = egid */ - egid != my_cred->cr_rgid && /* allow egid = rgid */ - egid != my_cred->cr_svgid)) && /* allow egid = svgid */ + egid != my_pcred->cr_groups[0] && /* allow no change of egid */ + egid != my_pcred->cr_gid && /* allow egid = egid */ + egid != my_pcred->cr_rgid && /* allow egid = rgid */ + egid != my_pcred->cr_svgid)) && /* allow egid = svgid */ (error = suser(my_cred, &p->p_acflag))) { /* allow root user any */ kauth_cred_unref(&my_cred); return (error); @@ -1285,8 +1317,8 @@ setregid(proc_t p, struct setregid_args *uap, __unused register_t *retval) /* get current credential and take a reference while we muck with it */ for (;;) { - uid_t new_egid = my_cred->cr_gid; - uid_t new_rgid = my_cred->cr_rgid; + uid_t new_egid = my_pcred->cr_gid; + uid_t new_rgid = my_pcred->cr_rgid; uid_t svgid = KAUTH_UID_NONE; @@ -1297,15 +1329,15 @@ setregid(proc_t p, struct setregid_args *uap, __unused register_t *retval) * passed in. The subsequent compare is safe, because it is * a pointer compare rather than a contents compare. */ - if (egid == KAUTH_UID_NONE && my_cred->cr_groups[0] != egid) { + if (egid == KAUTH_UID_NONE && my_pcred->cr_gid != egid) { /* changing the effective GID */ new_egid = egid; - OSBitOrAtomic(P_SUGID, (UInt32 *)&p->p_flag); + OSBitOrAtomic(P_SUGID, &p->p_flag); } - if (rgid != KAUTH_UID_NONE && my_cred->cr_rgid != rgid) { + if (rgid != KAUTH_UID_NONE && my_pcred->cr_rgid != rgid) { /* changing the real GID */ new_rgid = rgid; - OSBitOrAtomic(P_SUGID, (UInt32 *)&p->p_flag); + OSBitOrAtomic(P_SUGID, &p->p_flag); } /* * If the newly requested real gid or effective gid does @@ -1313,16 +1345,16 @@ setregid(proc_t p, struct setregid_args *uap, __unused register_t *retval) * new effective gid. We are protected from escalation * by the prechecking. */ - if (my_cred->cr_svgid != uap->rgid && - my_cred->cr_svgid != uap->egid) { + if (my_pcred->cr_svgid != uap->rgid && + my_pcred->cr_svgid != uap->egid) { svgid = new_egid; - OSBitOrAtomic(P_SUGID, (UInt32 *)&p->p_flag); + OSBitOrAtomic(P_SUGID, &p->p_flag); } my_new_cred = kauth_cred_setresgid(my_cred, rgid, egid, svgid); if (my_cred != my_new_cred) { - DEBUG_CRED_CHANGE("setregid(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); + 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); /* need to protect for a race where another thread @@ -1338,7 +1370,9 @@ setregid(proc_t p, struct setregid_args *uap, __unused register_t *retval) continue; } p->p_ucred = my_new_cred; - OSBitOrAtomic(P_SUGID, (UInt32 *)&p->p_flag); /* XXX redundant? */ + /* update cred on proc */ + PROC_UPDATE_CREDS_ONPROC(p); + OSBitOrAtomic(P_SUGID, &p->p_flag); /* XXX redundant? */ proc_unlock(p); } break; @@ -1360,7 +1394,7 @@ setregid(proc_t p, struct setregid_args *uap, __unused register_t *retval) * thread to the requested UID and single GID, and clears all other GIDs. */ int -settid(proc_t p, struct settid_args *uap, __unused register_t *retval) +settid(proc_t p, struct settid_args *uap, __unused int32_t *retval) { kauth_cred_t uc; struct uthread *uthread = get_bsdthread_info(current_thread()); @@ -1369,7 +1403,8 @@ settid(proc_t p, struct settid_args *uap, __unused register_t *retval) uid = uap->uid; gid = uap->gid; - AUDIT_ARG(uid, uid, gid, gid, 0); + AUDIT_ARG(uid, uid); + AUDIT_ARG(gid, gid); if (proc_suser(p) != 0) return (EPERM); @@ -1431,14 +1466,15 @@ settid(proc_t p, struct settid_args *uap, __unused register_t *retval) * When the assume argument is zero we revert back to our normal identity. */ int -settid_with_pid(proc_t p, struct settid_with_pid_args *uap, __unused register_t *retval) +settid_with_pid(proc_t p, struct settid_with_pid_args *uap, __unused int32_t *retval) { proc_t target_proc; struct uthread *uthread = get_bsdthread_info(current_thread()); kauth_cred_t my_cred, my_target_cred, my_new_cred; + posix_cred_t my_target_pcred; AUDIT_ARG(pid, uap->pid); - AUDIT_ARG(value, uap->assume); + AUDIT_ARG(value32, uap->assume); if (proc_suser(p) != 0) { return (EPERM); @@ -1483,7 +1519,8 @@ settid_with_pid(proc_t p, struct settid_with_pid_args *uap, __unused register_t kauth_cred_ref(uthread->uu_ucred); my_cred = uthread->uu_ucred; my_target_cred = kauth_cred_proc_ref(target_proc); - my_new_cred = kauth_cred_setuidgid(my_cred, my_target_cred->cr_uid, my_target_cred->cr_gid); + my_target_pcred = posix_cred_get(my_target_cred); + my_new_cred = kauth_cred_setuidgid(my_cred, my_target_pcred->cr_uid, my_target_pcred->cr_gid); if (my_cred != my_new_cred) uthread->uu_ucred = my_new_cred; @@ -1551,7 +1588,7 @@ settid_with_pid(proc_t p, struct settid_with_pid_args *uap, __unused register_t * 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 register_t *retval) +setgroups1(proc_t p, u_int gidsetsize, user_addr_t gidset, uid_t gmuid, __unused int32_t *retval) { u_int ngrp; gid_t newgroups[NGROUPS] = { 0 }; @@ -1639,13 +1676,15 @@ setgroups1(proc_t p, u_int gidsetsize, user_addr_t gidset, uid_t gmuid, __unused continue; } p->p_ucred = my_new_cred; - OSBitOrAtomic(P_SUGID, (UInt32 *)&p->p_flag); + /* update cred on proc */ + PROC_UPDATE_CREDS_ONPROC(p); + OSBitOrAtomic(P_SUGID, &p->p_flag); proc_unlock(p); } break; } /* Drop old proc reference or our extra reference */ - AUDIT_ARG(groupset, my_cred->cr_groups, ngrp); + AUDIT_ARG(groupset, posix_cred_get(my_cred)->cr_groups, ngrp); kauth_cred_unref(&my_cred); @@ -1686,7 +1725,7 @@ setgroups1(proc_t p, u_int gidsetsize, user_addr_t gidset, uid_t gmuid, __unused * See also: setgroups1() */ int -initgroups(proc_t p, struct initgroups_args *uap, __unused register_t *retval) +initgroups(proc_t p, struct initgroups_args *uap, __unused int32_t *retval) { DEBUG_CRED_ENTER("initgroups\n"); @@ -1720,7 +1759,7 @@ initgroups(proc_t p, struct initgroups_args *uap, __unused register_t *retval) * See also: setgroups1() */ int -setgroups(proc_t p, struct setgroups_args *uap, __unused register_t *retval) +setgroups(proc_t p, struct setgroups_args *uap, __unused int32_t *retval) { DEBUG_CRED_ENTER("setgroups\n"); @@ -1730,20 +1769,26 @@ setgroups(proc_t p, struct setgroups_args *uap, __unused register_t *retval) /* * Set the per-thread/per-process supplementary groups list. + * + * XXX implement setsgroups + * */ -#warning XXX implement setsgroups + int -setsgroups(__unused proc_t p, __unused struct setsgroups_args *uap, __unused register_t *retval) +setsgroups(__unused proc_t p, __unused struct setsgroups_args *uap, __unused int32_t *retval) { return(ENOTSUP); } /* * Set the per-thread/per-process whiteout groups list. + * + * XXX implement setwgroups + * */ -#warning XXX implement setwgroups + int -setwgroups(__unused proc_t p, __unused struct setwgroups_args *uap, __unused register_t *retval) +setwgroups(__unused proc_t p, __unused struct setwgroups_args *uap, __unused int32_t *retval) { return(ENOTSUP); } @@ -1796,45 +1841,6 @@ suser(kauth_cred_t cred, u_short *acflag) } -/* - * XXX This interface is going away; use kauth_cred_issuser() directly - * XXX instead. - */ -int -is_suser(void) -{ - proc_t p = current_proc(); - - if (!p) - return (0); - - return (proc_suser(p) == 0); -} - - -/* - * XXX This interface is going away; use kauth_cred_issuser() directly - * XXX instead. - */ -int -is_suser1(void) -{ - proc_t p = current_proc(); - kauth_cred_t my_cred; - int err; - - if (!p) - return (0); - - my_cred = kauth_cred_proc_ref(p); - - err = (suser(my_cred, &p->p_acflag) == 0 || - my_cred->cr_ruid == 0 || my_cred->cr_svuid == 0); - kauth_cred_unref(&my_cred); - return(err); -} - - /* * getlogin * @@ -1859,7 +1865,7 @@ is_suser1(void) * XXX: Belongs in kern_proc.c */ int -getlogin(proc_t p, struct getlogin_args *uap, __unused register_t *retval) +getlogin(proc_t p, struct getlogin_args *uap, __unused int32_t *retval) { char buffer[MAXLOGNAME+1]; struct session * sessp; @@ -1899,10 +1905,10 @@ getlogin(proc_t p, struct getlogin_args *uap, __unused register_t *retval) * XXX: Belongs in kern_proc.c */ int -setlogin(proc_t p, struct setlogin_args *uap, __unused register_t *retval) +setlogin(proc_t p, struct setlogin_args *uap, __unused int32_t *retval) { int error; - int dummy=0; + size_t dummy=0; char buffer[MAXLOGNAME+1]; struct session * sessp; @@ -1945,6 +1951,7 @@ set_security_token(proc_t p) 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; /* @@ -1961,10 +1968,12 @@ set_security_token(proc_t p) } my_cred = kauth_cred_proc_ref(p); + my_pcred = posix_cred_get(my_cred); + /* XXX mach_init doesn't have a p_ucred when it calls this function */ if (IS_VALID_CRED(my_cred)) { sec_token.val[0] = kauth_cred_getuid(my_cred); - sec_token.val[1] = my_cred->cr_gid; + sec_token.val[1] = kauth_cred_getgid(my_cred); } else { sec_token.val[0] = 0; sec_token.val[1] = 0; @@ -1979,13 +1988,13 @@ set_security_token(proc_t p) * the user of the trailer from future representation * changes. */ - audit_token.val[0] = my_cred->cr_au.ai_auid; - audit_token.val[1] = my_cred->cr_uid; - audit_token.val[2] = my_cred->cr_gid; - audit_token.val[3] = my_cred->cr_ruid; - audit_token.val[4] = my_cred->cr_rgid; + 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_au.ai_asid; + audit_token.val[6] = my_cred->cr_audit.as_aia_p->ai_asid; audit_token.val[7] = p->p_idversion; #if CONFIG_MACF_MACH @@ -2014,12 +2023,13 @@ __private_extern__ void cru2x(kauth_cred_t cr, struct xucred *xcr) { + posix_cred_t pcr = posix_cred_get(cr); bzero(xcr, sizeof(*xcr)); xcr->cr_version = XUCRED_VERSION; xcr->cr_uid = kauth_cred_getuid(cr); - xcr->cr_ngroups = cr->cr_ngroups; - bcopy(cr->cr_groups, xcr->cr_groups, sizeof(xcr->cr_groups)); + xcr->cr_ngroups = pcr->cr_ngroups; + bcopy(pcr->cr_groups, xcr->cr_groups, sizeof(xcr->cr_groups)); } #if CONFIG_LCTX @@ -2032,7 +2042,7 @@ cru2x(kauth_cred_t cr, struct xucred *xcr) * LCTX by its own locks. */ int -setlcid(proc_t p0, struct setlcid_args *uap, __unused register_t *retval) +setlcid(proc_t p0, struct setlcid_args *uap, __unused int32_t *retval) { proc_t p; struct lctx *l; @@ -2040,7 +2050,7 @@ setlcid(proc_t p0, struct setlcid_args *uap, __unused register_t *retval) int refheld = 0; AUDIT_ARG(pid, uap->pid); - AUDIT_ARG(value, uap->lcid); + AUDIT_ARG(value32, uap->lcid); if (uap->pid == LCID_PROC_SELF) { /* Create/Join/Leave */ p = p0; } else { /* Adopt/Orphan */ @@ -2061,7 +2071,7 @@ setlcid(proc_t p0, struct setlcid_args *uap, __unused register_t *retval) case LCID_REMOVE: /* Only root may Leave/Orphan. */ - if (!is_suser1()) { + if (!kauth_cred_issuser(kauth_cred_get())) { error = EPERM; goto out; } @@ -2105,7 +2115,7 @@ setlcid(proc_t p0, struct setlcid_args *uap, __unused register_t *retval) default: /* Only root may Join/Adopt. */ - if (!is_suser1()) { + if (!kauth_cred_issuser(kauth_cred_get())) { error = EPERM; goto out; } @@ -2138,7 +2148,7 @@ out: * protected by the all-context lock. */ int -getlcid(proc_t p0, struct getlcid_args *uap, register_t *retval) +getlcid(proc_t p0, struct getlcid_args *uap, int32_t *retval) { proc_t p; int error = 0; @@ -2175,14 +2185,14 @@ getlcid(proc_t p0, struct getlcid_args *uap, register_t *retval) } #else /* LCTX */ int -setlcid(proc_t p0, struct setlcid_args *uap, register_t *retval) +setlcid(proc_t p0, struct setlcid_args *uap, int32_t *retval) { return (ENOSYS); } int -getlcid(proc_t p0, struct getlcid_args *uap, register_t *retval) +getlcid(proc_t p0, struct getlcid_args *uap, int32_t *retval) { return (ENOSYS);