git: 5d46d11772c3 - main - proc_set_cred(): Allow 'newcred' to have multiple references

From: Olivier Certner <olce_at_FreeBSD.org>
Date: Sun, 09 Nov 2025 22:39:11 UTC
The branch main has been updated by olce:

URL: https://cgit.FreeBSD.org/src/commit/?id=5d46d11772c3280fd1c8ae09f20ce6c57f631c30

commit 5d46d11772c3280fd1c8ae09f20ce6c57f631c30
Author:     Olivier Certner <olce@FreeBSD.org>
AuthorDate: 2025-11-06 22:25:57 +0000
Commit:     Olivier Certner <olce@FreeBSD.org>
CommitDate: 2025-11-09 22:38:10 +0000

    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
---
 sys/kern/kern_prot.c | 8 +++-----
 1 file 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);