git: 2be5127c4a31 - main - setcred(): Fix RACCT resource accounting on credentials change

From: Olivier Certner <olce_at_FreeBSD.org>
Date: Sun, 02 Nov 2025 18:17:15 UTC
The branch main has been updated by olce:

URL: https://cgit.FreeBSD.org/src/commit/?id=2be5127c4a31bacac9b4158395bfa844f6033626

commit 2be5127c4a31bacac9b4158395bfa844f6033626
Author:     Olivier Certner <olce@FreeBSD.org>
AuthorDate: 2025-10-29 17:07:59 +0000
Commit:     Olivier Certner <olce@FreeBSD.org>
CommitDate: 2025-11-02 18:15:30 +0000

    setcred(): Fix RACCT resource accounting on credentials change
    
    When credentials are changed, we need to adjust the sum of resources
    associated to the initial and new process' user IDs (and old and new
    login classes and jails, but setcred() does not change them) for them to
    stay consistent.
    
    PR:             290352
    MFC after:      3 days
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D53457
---
 sys/kern/kern_prot.c | 17 ++++++++++++++++-
 1 file changed, 16 insertions(+), 1 deletion(-)

diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
index df725cfebd97..3c145851b683 100644
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -696,7 +696,7 @@ kern_setcred(struct thread *const td, const u_int flags,
 	gid_t *groups = NULL;
 	gid_t smallgroups[CRED_SMALLGROUPS_NB];
 	int error;
-	bool cred_set;
+	bool cred_set = false;
 
 	/* Bail out on unrecognized flags. */
 	if (flags & ~SETCREDF_MASK)
@@ -839,17 +839,32 @@ kern_setcred(struct thread *const td, const u_int flags,
 	if (cred_set) {
 		setsugid(p);
 		to_free_cred = old_cred;
+#ifdef RACCT
+		racct_proc_ucred_changed(p, old_cred, new_cred);
+#endif
+#ifdef RCTL
+		crhold(new_cred);
+#endif
 		MPASS(error == 0);
 	} else
 		error = EAGAIN;
 
 unlock_finish:
 	PROC_UNLOCK(p);
+
 	/*
 	 * Part 3: After releasing the process lock, we perform cleanups and
 	 * finishing operations.
 	 */
 
+#ifdef RCTL
+	if (cred_set) {
+		rctl_proc_ucred_changed(p, new_cred);
+		/* Paired with the crhold() just above. */
+		crfree(new_cred);
+	}
+#endif
+
 #ifdef MAC
 	if (mac_set_proc_data != NULL)
 		mac_set_proc_finish(td, proc_label_set, mac_set_proc_data);