cred: add proc_set_cred helper
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.
This commit is contained in:
parent
95246f3d83
commit
daf63fd2f9
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=280130
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -725,7 +725,7 @@ do_execve(td, args, mac_p)
|
||||
*/
|
||||
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 @@ do_execve(td, args, mac_p)
|
||||
PROC_LOCK(p);
|
||||
change_svuid(newcred, newcred->cr_uid);
|
||||
change_svgid(newcred, newcred->cr_gid);
|
||||
p->p_ucred = newcred;
|
||||
proc_set_cred(p, newcred);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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)
|
||||
{
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user