/*
 * Called with a modifying token held, but must still obtain p_spin to
 * actually replace p_ucred to handle races against syscall entry from
 * other threads which cache p_ucred->td_ucred.
 *
 * (the threads will only get the spin-lock, and they only need to in
 *  the case where td_ucred != p_ucred so this is optimal).
 */
struct ucred *
cratom_proc(struct proc *p)
{
	struct ucred *oldcr;
	struct ucred *newcr;

	oldcr = p->p_ucred;
	if (oldcr->cr_ref == 1)
		return(oldcr);

	newcr = crget();	/* this might block */
	oldcr = p->p_ucred;	/* so re-cache oldcr (do not re-test) */
	*newcr = *oldcr;
	if (newcr->cr_uidinfo)
		uihold(newcr->cr_uidinfo);
	if (newcr->cr_ruidinfo)
		uihold(newcr->cr_ruidinfo);
	if (jailed(newcr))
		prison_hold(newcr->cr_prison);
	newcr->cr_ref = 1;

	spin_lock(&p->p_spin);
	p->p_ucred = newcr;
	spin_unlock(&p->p_spin);
	crfree(oldcr);

	return newcr;
}
Пример #2
0
/*
 * Dup cred struct to a new held one.
 */
struct ucred *
crdup(struct ucred *cr)
{
	struct ucred *newcr;

	newcr = crget();
	*newcr = *cr;
	if (newcr->cr_uidinfo)
		uihold(newcr->cr_uidinfo);
	if (newcr->cr_ruidinfo)
		uihold(newcr->cr_ruidinfo);
	if (jailed(newcr))
		prison_hold(newcr->cr_prison);
	newcr->cr_ref = 1;
	return (newcr);
}
Пример #3
0
/*
 * Copy cred structure to a new one and free the old one.
 *
 * MPSAFE (*cr must be stable)
 */
struct ucred *
crcopy(struct ucred *cr)
{
	struct ucred *newcr;

	if (cr->cr_ref == 1)
		return (cr);
	newcr = crget();
	*newcr = *cr;
	if (newcr->cr_uidinfo)
		uihold(newcr->cr_uidinfo);
	if (newcr->cr_ruidinfo)
		uihold(newcr->cr_ruidinfo);
	if (jailed(newcr))
		prison_hold(newcr->cr_prison);
	newcr->cr_ref = 1;
	crfree(cr);
	return (newcr);
}
Пример #4
0
/*
 * Atomize a cred structure so it can be modified without polluting
 * other references to it.
 *
 * MPSAFE (however, *pcr must be stable)
 */
struct ucred *
cratom(struct ucred **pcr)
{
	struct ucred *oldcr;
	struct ucred *newcr;

	oldcr = *pcr;
	if (oldcr->cr_ref == 1)
		return (oldcr);
	newcr = crget();
	*newcr = *oldcr;
	if (newcr->cr_uidinfo)
		uihold(newcr->cr_uidinfo);
	if (newcr->cr_ruidinfo)
		uihold(newcr->cr_ruidinfo);
	if (jailed(newcr))
		prison_hold(newcr->cr_prison);
	newcr->cr_ref = 1;
	crfree(oldcr);
	*pcr = newcr;
	return (newcr);
}
/*
 * Atomize a cred structure so it can be modified without polluting
 * other references to it.
 *
 * MPSAFE (however, *pcr must be stable)
 */
struct ucred *
cratom(struct ucred **pcr)
{
	struct ucred *oldcr;
	struct ucred *newcr;

	oldcr = *pcr;
	if (oldcr->cr_ref == 1)
		return (oldcr);
	newcr = crget();	/* this might block */
	oldcr = *pcr;		/* re-cache after potentially blocking */
	*newcr = *oldcr;
	if (newcr->cr_uidinfo)
		uihold(newcr->cr_uidinfo);
	if (newcr->cr_ruidinfo)
		uihold(newcr->cr_ruidinfo);
	if (jailed(newcr))
		prison_hold(newcr->cr_prison);
	newcr->cr_ref = 1;
	crfree(oldcr);
	*pcr = newcr;

	return (newcr);
}