]> xenbits.xensource.com Git - people/julieng/freebsd.git/commitdiff
cred: add proc_set_cred helper
authormjg <mjg@FreeBSD.org>
Mon, 16 Mar 2015 00:10:03 +0000 (00:10 +0000)
committermjg <mjg@FreeBSD.org>
Mon, 16 Mar 2015 00:10:03 +0000 (00:10 +0000)
The goal here is to provide one place altering process credentials.

This eases debugging and opens up posibilities to do additional work when such
an action is performed.

14 files changed:
sys/compat/linux/linux_misc.c
sys/compat/linux/linux_uid16.c
sys/kern/init_main.c
sys/kern/kern_exec.c
sys/kern/kern_exit.c
sys/kern/kern_fork.c
sys/kern/kern_jail.c
sys/kern/kern_loginclass.c
sys/kern/kern_prot.c
sys/kern/sys_capability.c
sys/security/audit/audit_syscalls.c
sys/security/mac/mac_syscalls.c
sys/security/mac_lomac/mac_lomac.c
sys/sys/ucred.h

index 93dd80db0640b75deb8d9534bdf8b51d63bac1e1..ec531d39df1c43a9e8591b818c32bb470f142551 100644 (file)
@@ -1138,7 +1138,7 @@ linux_setgroups(struct thread *td, struct linux_setgroups_args *args)
                newcred->cr_ngroups = 1;
 
        setsugid(p);
-       p->p_ucred = newcred;
+       proc_set_cred(p, newcred);
        PROC_UNLOCK(p);
        crfree(oldcred);
        error = 0;
index 61f3030049e6e39c003d08e348e4bd3fb1b44edc..8c7c7606920a853b791aa67cb5ac82c7db6420a2 100644 (file)
@@ -213,7 +213,7 @@ linux_setgroups16(struct thread *td, struct linux_setgroups16_args *args)
                newcred->cr_ngroups = 1;
 
        setsugid(td->td_proc);
-       p->p_ucred = newcred;
+       proc_set_cred(p, newcred);
        PROC_UNLOCK(p);
        crfree(oldcred);
        error = 0;
index 57e2ee91caf06b572762dafdddf30bfb45160a99..82cf63f5f3548fb6b13afcbd9aace9ec69932674 100644 (file)
@@ -432,6 +432,7 @@ proc0_init(void *dummy __unused)
 {
        struct proc *p;
        struct thread *td;
+       struct ucred *newcred;
        vm_paddr_t pageablemem;
        int i;
 
@@ -508,19 +509,20 @@ proc0_init(void *dummy __unused)
        callout_init(&td->td_slpcallout, CALLOUT_MPSAFE);
 
        /* Create credentials. */
-       p->p_ucred = crget();
-       p->p_ucred->cr_ngroups = 1;     /* group 0 */
-       p->p_ucred->cr_uidinfo = uifind(0);
-       p->p_ucred->cr_ruidinfo = uifind(0);
-       p->p_ucred->cr_prison = &prison0;
-       p->p_ucred->cr_loginclass = loginclass_find("default");
+       newcred = crget();
+       newcred->cr_ngroups = 1;        /* group 0 */
+       newcred->cr_uidinfo = uifind(0);
+       newcred->cr_ruidinfo = uifind(0);
+       newcred->cr_prison = &prison0;
+       newcred->cr_loginclass = loginclass_find("default");
+       proc_set_cred(p, newcred);
 #ifdef AUDIT
-       audit_cred_kproc0(p->p_ucred);
+       audit_cred_kproc0(newcred);
 #endif
 #ifdef MAC
-       mac_cred_create_swapper(p->p_ucred);
+       mac_cred_create_swapper(newcred);
 #endif
-       td->td_ucred = crhold(p->p_ucred);
+       td->td_ucred = crhold(newcred);
 
        /* Create sigacts. */
        p->p_sigacts = sigacts_alloc();
@@ -836,7 +838,7 @@ create_init(const void *udata __unused)
 #ifdef AUDIT
        audit_cred_proc1(newcred);
 #endif
-       initproc->p_ucred = newcred;
+       proc_set_cred(initproc, newcred);
        PROC_UNLOCK(initproc);
        sx_xunlock(&proctree_lock);
        crfree(oldcred);
index 5b80f5c6a147456bf758280f5ffbe47de41458be..25335cec5da540ad9a48d6498cde2f701166c8e4 100644 (file)
@@ -725,7 +725,7 @@ interpret:
                 */
                change_svuid(newcred, newcred->cr_uid);
                change_svgid(newcred, newcred->cr_gid);
-               p->p_ucred = newcred;
+               proc_set_cred(p, newcred);
        } else {
                if (oldcred->cr_uid == oldcred->cr_ruid &&
                    oldcred->cr_gid == oldcred->cr_rgid)
@@ -751,7 +751,7 @@ interpret:
                        PROC_LOCK(p);
                        change_svuid(newcred, newcred->cr_uid);
                        change_svgid(newcred, newcred->cr_gid);
-                       p->p_ucred = newcred;
+                       proc_set_cred(p, newcred);
                }
        }
 
index ef8dcb2d38026d6df6b58fc89d375acbfa91d76a..e988422e13f9cc247ab89ada5a5188998cdb17cb 100644 (file)
@@ -916,7 +916,7 @@ proc_reap(struct thread *td, struct proc *p, int *status, int options)
         * Free credentials, arguments, and sigacts.
         */
        crfree(p->p_ucred);
-       p->p_ucred = NULL;
+       proc_set_cred(p, NULL);
        pargs_drop(p->p_args);
        p->p_args = NULL;
        sigacts_free(p->p_sigacts);
index 2c83422008a8512405cdfafc84eaeedee183dc44..ae86fe17a407e5437fa5bf8e4e71c721dba511fa 100644 (file)
@@ -410,7 +410,8 @@ do_fork(struct thread *td, int flags, struct proc *p2, struct thread *td2,
        bzero(&p2->p_startzero,
            __rangeof(struct proc, p_startzero, p_endzero));
 
-       p2->p_ucred = crhold(td->td_ucred);
+       crhold(td->td_ucred);
+       proc_set_cred(p2, td->td_ucred);
 
        /* Tell the prison that we exist. */
        prison_proc_hold(p2->p_ucred->cr_prison);
@@ -869,7 +870,7 @@ fork1(struct thread *td, int flags, int pages, struct proc **procp,
         * XXX: This is ugly; when we copy resource usage, we need to bump
         *      per-cred resource counters.
         */
-       newproc->p_ucred = p1->p_ucred;
+       proc_set_cred(newproc, p1->p_ucred);
 
        /*
         * Initialize resource accounting for the child process.
index 592c177d01aca882b43512ff7d4c252cefa444ff..e61bb4789314b85d61372774c2f0e43994c00472 100644 (file)
@@ -2445,7 +2445,7 @@ do_jail_attach(struct thread *td, struct prison *pr)
        setsugid(p);
        crcopy(newcred, oldcred);
        newcred->cr_prison = pr;
-       p->p_ucred = newcred;
+       proc_set_cred(p, newcred);
        PROC_UNLOCK(p);
 #ifdef RACCT
        racct_proc_ucred_changed(p, oldcred, newcred);
index c0946efe8392c103c26476ceee01169c55a54326..62e642140c456a7651ae5df57ec5a3412d380c52 100644 (file)
@@ -221,7 +221,7 @@ sys_setloginclass(struct thread *td, struct setloginclass_args *uap)
        PROC_LOCK(p);
        oldcred = crcopysafe(p, newcred);
        newcred->cr_loginclass = newlc;
-       p->p_ucred = newcred;
+       proc_set_cred(p, newcred);
        PROC_UNLOCK(p);
 #ifdef RACCT
        racct_proc_ucred_changed(p, oldcred, newcred);
index 1043915658be08f8147ac6dc690d2a8e69ad8297..72c9f652fed41dc4b803ff97c8b26ff6be0cd7b0 100644 (file)
@@ -579,7 +579,7 @@ sys_setuid(struct thread *td, struct setuid_args *uap)
                change_euid(newcred, uip);
                setsugid(p);
        }
-       p->p_ucred = newcred;
+       proc_set_cred(p, newcred);
        PROC_UNLOCK(p);
 #ifdef RACCT
        racct_proc_ucred_changed(p, oldcred, newcred);
@@ -638,7 +638,7 @@ sys_seteuid(struct thread *td, struct seteuid_args *uap)
                change_euid(newcred, euip);
                setsugid(p);
        }
-       p->p_ucred = newcred;
+       proc_set_cred(p, newcred);
        PROC_UNLOCK(p);
        uifree(euip);
        crfree(oldcred);
@@ -738,7 +738,7 @@ sys_setgid(struct thread *td, struct setgid_args *uap)
                change_egid(newcred, gid);
                setsugid(p);
        }
-       p->p_ucred = newcred;
+       proc_set_cred(p, newcred);
        PROC_UNLOCK(p);
        crfree(oldcred);
        return (0);
@@ -784,7 +784,7 @@ sys_setegid(struct thread *td, struct setegid_args *uap)
                change_egid(newcred, egid);
                setsugid(p);
        }
-       p->p_ucred = newcred;
+       proc_set_cred(p, newcred);
        PROC_UNLOCK(p);
        crfree(oldcred);
        return (0);
@@ -864,7 +864,7 @@ kern_setgroups(struct thread *td, u_int ngrp, gid_t *groups)
                crsetgroups_locked(newcred, ngrp, groups);
        }
        setsugid(p);
-       p->p_ucred = newcred;
+       proc_set_cred(p, newcred);
        PROC_UNLOCK(p);
        crfree(oldcred);
        return (0);
@@ -927,7 +927,7 @@ sys_setreuid(register struct thread *td, struct setreuid_args *uap)
                change_svuid(newcred, newcred->cr_uid);
                setsugid(p);
        }
-       p->p_ucred = newcred;
+       proc_set_cred(p, newcred);
        PROC_UNLOCK(p);
 #ifdef RACCT
        racct_proc_ucred_changed(p, oldcred, newcred);
@@ -994,7 +994,7 @@ sys_setregid(register struct thread *td, struct setregid_args *uap)
                change_svgid(newcred, newcred->cr_groups[0]);
                setsugid(p);
        }
-       p->p_ucred = newcred;
+       proc_set_cred(p, newcred);
        PROC_UNLOCK(p);
        crfree(oldcred);
        return (0);
@@ -1068,7 +1068,7 @@ sys_setresuid(register struct thread *td, struct setresuid_args *uap)
                change_svuid(newcred, suid);
                setsugid(p);
        }
-       p->p_ucred = newcred;
+       proc_set_cred(p, newcred);
        PROC_UNLOCK(p);
 #ifdef RACCT
        racct_proc_ucred_changed(p, oldcred, newcred);
@@ -1147,7 +1147,7 @@ sys_setresgid(register struct thread *td, struct setresgid_args *uap)
                change_svgid(newcred, sgid);
                setsugid(p);
        }
-       p->p_ucred = newcred;
+       proc_set_cred(p, newcred);
        PROC_UNLOCK(p);
        crfree(oldcred);
        return (0);
@@ -1953,6 +1953,31 @@ cred_update_thread(struct thread *td)
                crfree(cred);
 }
 
+/*
+ * Change process credentials.
+ * Callers are responsible for providing the reference for current credentials
+ * and for freeing old ones.
+ *
+ * Process has to be locked except when it does not have credentials (as it
+ * should not be visible just yet) or when newcred is NULL (as this can be
+ * only used when the process is about to be freed, at which point it should
+ * not be visible anymore).
+ */
+struct ucred *
+proc_set_cred(struct proc *p, struct ucred *newcred)
+{
+       struct ucred *oldcred;
+
+       if (newcred == NULL)
+               MPASS(p->p_state == PRS_ZOMBIE);
+       else if (p->p_ucred != NULL)
+               PROC_LOCK_ASSERT(p, MA_OWNED);
+
+       oldcred = p->p_ucred;
+       p->p_ucred = newcred;
+       return (oldcred);
+}
+
 struct ucred *
 crcopysafe(struct proc *p, struct ucred *cr)
 {
index 79975513a4c760416f33106a23109335dde905bc..b0b77fe0a9b37563c9f132e9891b447ca44d00e2 100644 (file)
@@ -104,7 +104,7 @@ sys_cap_enter(struct thread *td, struct cap_enter_args *uap)
        PROC_LOCK(p);
        oldcred = crcopysafe(p, newcred);
        newcred->cr_flags |= CRED_FLAG_CAPMODE;
-       p->p_ucred = newcred;
+       proc_set_cred(p, newcred);
        PROC_UNLOCK(p);
        crfree(oldcred);
        return (0);
index 6ef606b777ac859a7f1f43dbbbc26015aef131c9..90d811ddbaf40a3d70d5bb240ed2ac89b07b0fb5 100644 (file)
@@ -461,7 +461,7 @@ sys_auditon(struct thread *td, struct auditon_args *uap)
                    udata.au_aupinfo.ap_mask.am_success;
                newcred->cr_audit.ai_mask.am_failure =
                    udata.au_aupinfo.ap_mask.am_failure;
-               tp->p_ucred = newcred;
+               proc_set_cred(tp, newcred);
                PROC_UNLOCK(tp);
                crfree(oldcred);
                break;
@@ -600,7 +600,7 @@ sys_setauid(struct thread *td, struct setauid_args *uap)
        if (error)
                goto fail;
        newcred->cr_audit.ai_auid = id;
-       td->td_proc->p_ucred = newcred;
+       proc_set_cred(td->td_proc, newcred);
        PROC_UNLOCK(td->td_proc);
        crfree(oldcred);
        return (0);
@@ -671,7 +671,7 @@ sys_setaudit(struct thread *td, struct setaudit_args *uap)
        newcred->cr_audit.ai_termid.at_addr[0] = ai.ai_termid.machine;
        newcred->cr_audit.ai_termid.at_port = ai.ai_termid.port;
        newcred->cr_audit.ai_termid.at_type = AU_IPv4;
-       td->td_proc->p_ucred = newcred;
+       proc_set_cred(td->td_proc, newcred);
        PROC_UNLOCK(td->td_proc);
        crfree(oldcred);
        return (0);
@@ -728,7 +728,7 @@ sys_setaudit_addr(struct thread *td, struct setaudit_addr_args *uap)
        if (error)
                goto fail;
        newcred->cr_audit = aia;
-       td->td_proc->p_ucred = newcred;
+       proc_set_cred(td->td_proc, newcred);
        PROC_UNLOCK(td->td_proc);
        crfree(oldcred);
        return (0);
index f084ea48a183cf97cf95a9328d89a81f0f05001e..304d3135918321d8537929fedca55b155fbcff4e 100644 (file)
@@ -208,7 +208,7 @@ sys___mac_set_proc(struct thread *td, struct __mac_set_proc_args *uap)
        setsugid(p);
        crcopy(newcred, oldcred);
        mac_cred_relabel(newcred, intlabel);
-       p->p_ucred = newcred;
+       proc_set_cred(p, newcred);
 
        PROC_UNLOCK(p);
        crfree(oldcred);
index 32ae2239a2d31aaa887ede620f1c22344f00b7f4..5607940cbdc08b9f981914deea90377a0df97fc6 100644 (file)
@@ -2255,7 +2255,7 @@ lomac_thread_userret(struct thread *td)
                crcopy(newcred, oldcred);
                crhold(newcred);
                lomac_copy(&subj->mac_lomac, SLOT(newcred->cr_label));
-               p->p_ucred = newcred;
+               proc_set_cred(p, newcred);
                crfree(oldcred);
                dodrop = 1;
        out:
index a6531c426c4e690869453b2cf4813e8c781a165a..2b42b018cd54f5dbcfe1e1d6aebe8e94c48ed6ad 100644 (file)
@@ -106,6 +106,7 @@ void        crcopy(struct ucred *dest, struct ucred *src);
 struct ucred   *crcopysafe(struct proc *p, struct ucred *cr);
 struct ucred   *crdup(struct ucred *cr);
 void   cred_update_thread(struct thread *td);
+struct ucred   *proc_set_cred(struct proc *p, struct ucred *cr);
 void   crfree(struct ucred *cr);
 struct ucred   *crget(void);
 struct ucred   *crhold(struct ucred *cr);