aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOlivier Certner <olce@FreeBSD.org>2025-11-06 22:25:57 +0000
committerOlivier Certner <olce@FreeBSD.org>2025-11-09 22:38:10 +0000
commit5d46d11772c3280fd1c8ae09f20ce6c57f631c30 (patch)
tree8fbd9e4d56b5dbc7830cc8190a5bb5ad544e170a
parent39acb7fd86eda721df402c2f1368b78cede161c3 (diff)
proc_set_cred(): Allow 'newcred' to have multiple references
This is an extension needed by next commit, where some additional reference is kept on the credentials to be set on a process in order to keep these credentials alive even after the process lock is released (an intervening reset of process credentials could release the reference that the process holds). Only 'cr_users' is incremented, as the reference (counted in 'cr_ref') comes from the caller, who passes it to the process. Reviewed by: kib, markj MFC after: 1 week Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D53636
-rw-r--r--sys/kern/kern_prot.c8
1 files changed, 3 insertions, 5 deletions
diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
index 3c145851b683..dc8751ddfbf6 100644
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -2792,10 +2792,6 @@ _proc_set_cred(struct proc *p, struct ucred *newcred, bool enforce_proc_lim)
MPASS(oldcred != NULL);
PROC_LOCK_ASSERT(p, MA_OWNED);
- KASSERT(newcred->cr_users == 0, ("%s: users %d not 0 on cred %p",
- __func__, newcred->cr_users, newcred));
- KASSERT(newcred->cr_ref == 1, ("%s: ref %ld not 1 on cred %p",
- __func__, newcred->cr_ref, newcred));
if (newcred->cr_ruidinfo != oldcred->cr_ruidinfo) {
/*
@@ -2821,8 +2817,10 @@ _proc_set_cred(struct proc *p, struct ucred *newcred, bool enforce_proc_lim)
__func__, oldcred->cr_users, oldcred));
oldcred->cr_users--;
mtx_unlock(&oldcred->cr_mtx);
+ mtx_lock(&newcred->cr_mtx);
+ newcred->cr_users++;
+ mtx_unlock(&newcred->cr_mtx);
p->p_ucred = newcred;
- newcred->cr_users = 1;
PROC_UPDATE_COW(p);
if (newcred->cr_ruidinfo != oldcred->cr_ruidinfo)
(void)chgproccnt(oldcred->cr_ruidinfo, -1, 0);