git: f4315ff8b3fe - main - kern: Fix credentials leaks on RACCT but no RCTL

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

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

commit f4315ff8b3fee71eb0098864a84618f2f8ba85d5
Author:     Olivier Certner <olce@FreeBSD.org>
AuthorDate: 2025-10-29 16:46:39 +0000
Commit:     Olivier Certner <olce@FreeBSD.org>
CommitDate: 2025-11-02 18:15:30 +0000

    kern: Fix credentials leaks on RACCT but no RCTL
    
    Affected system calls: setuid(), setreuid(), setresuid(), jail_attach(),
    setloginclass().
    
    In these system calls, the crhold() calls that, on RACCT, make the
    just-installed process credentials survive a concurrent change of the
    same credentials just after PROC_UNLOCK() were not matched by
    a corresponding crfree() when RCTL is off.  In fact, in that latter
    case, they are simply not necessary, so wrap them with '#ifdef RCTL'
    stances.  'kern_rctl.c' causes a compile error if RACCT is not defined
    but RCTL is, so ease reading by not nesting '#ifdef's.
    
    MFC after:      3 days
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D53456
---
 sys/kern/kern_jail.c       | 2 ++
 sys/kern/kern_loginclass.c | 2 ++
 sys/kern/kern_prot.c       | 6 ++++++
 3 files changed, 10 insertions(+)

diff --git a/sys/kern/kern_jail.c b/sys/kern/kern_jail.c
index 267b60ffb5bc..523b7e314a10 100644
--- a/sys/kern/kern_jail.c
+++ b/sys/kern/kern_jail.c
@@ -3047,6 +3047,8 @@ do_jail_attach(struct thread *td, struct prison *pr, int drflags)
 	setsugid(p);
 #ifdef RACCT
 	racct_proc_ucred_changed(p, oldcred, newcred);
+#endif
+#ifdef RCTL
 	crhold(newcred);
 #endif
 	PROC_UNLOCK(p);
diff --git a/sys/kern/kern_loginclass.c b/sys/kern/kern_loginclass.c
index 55db6c28a1db..0c111c4f78d8 100644
--- a/sys/kern/kern_loginclass.c
+++ b/sys/kern/kern_loginclass.c
@@ -225,6 +225,8 @@ sys_setloginclass(struct thread *td, struct setloginclass_args *uap)
 	proc_set_cred(p, newcred);
 #ifdef RACCT
 	racct_proc_ucred_changed(p, oldcred, newcred);
+#endif
+#ifdef RCTL
 	crhold(newcred);
 #endif
 	PROC_UNLOCK(p);
diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
index a4c5bcc52529..df725cfebd97 100644
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -982,6 +982,8 @@ sys_setuid(struct thread *td, struct setuid_args *uap)
 	proc_set_cred(p, newcred);
 #ifdef RACCT
 	racct_proc_ucred_changed(p, oldcred, newcred);
+#endif
+#ifdef RCTL
 	crhold(newcred);
 #endif
 	PROC_UNLOCK(p);
@@ -1390,6 +1392,8 @@ sys_setreuid(struct thread *td, struct setreuid_args *uap)
 	proc_set_cred(p, newcred);
 #ifdef RACCT
 	racct_proc_ucred_changed(p, oldcred, newcred);
+#endif
+#ifdef RCTL
 	crhold(newcred);
 #endif
 	PROC_UNLOCK(p);
@@ -1536,6 +1540,8 @@ sys_setresuid(struct thread *td, struct setresuid_args *uap)
 	proc_set_cred(p, newcred);
 #ifdef RACCT
 	racct_proc_ucred_changed(p, oldcred, newcred);
+#endif
+#ifdef RCTL
 	crhold(newcred);
 #endif
 	PROC_UNLOCK(p);