The branch main has been updated by kevans:

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

commit 28f618fcc2b42066f68a9459e4178adffe08d35b
Author:     Kyle Evans <kev...@freebsd.org>
AuthorDate: 2025-08-04 23:09:58 +0000
Commit:     Kyle Evans <kev...@freebsd.org>
CommitDate: 2025-08-04 23:09:58 +0000

    kern: fix a panic in crcopysafe() found by syzkaller
    
    crcopysafe() attempts to crextend() the new ucred's group allocation
    with the number of allocated group slots (`cr_asize`) from the ucred to
    copy rather than the latter's actual number of supplementary groups.
    However, the number of allocated group slots can exceed `ngroups_max`
    for certain values of it (because of rounding to the next power-of-2 or
    page on allocation), making `crextend()` trip on a check that the passed
    value should be lower than `ngroups_max`.
    
    This was not a problem before be1f7435ef218b1 because the effective max
    storage was NGROUPS_MAX + 1 (1024) to account for the egid being
    included in cr_groups.  Now that we're back down to NGROUPS_MAX, the max
    allocation will tend to be 1024 and exceed our max groups.
    
    Switch crcopysafe() to extend until we have enough allocated to fit
    the previous group set, and call crextend() with the number of groups
    that the old ucred had.  This avoids relying on implementation details
    of crextend() up-sizing our requests and ensures we only have as large
    of an allocation as we need to fulfill the request.
    
    Reviewed by:    olce
    Reported by:    syzbot+4e68da43c26f357a2...@syzkaller.appspotmail.com
    Fixes:  be1f7435ef218b1 ("kern: start tracking cr_gid outside [...]")
    Differential Revision:  https://reviews.freebsd.org/D51660
---
 sys/kern/kern_prot.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sys/kern/kern_prot.c b/sys/kern/kern_prot.c
index 6bdef84a34c1..bbb622547598 100644
--- a/sys/kern/kern_prot.c
+++ b/sys/kern/kern_prot.c
@@ -2773,8 +2773,8 @@ crcopysafe(struct proc *p, struct ucred *cr)
        PROC_LOCK_ASSERT(p, MA_OWNED);
 
        oldcred = p->p_ucred;
-       while (cr->cr_agroups < oldcred->cr_agroups) {
-               groups = oldcred->cr_agroups;
+       while (cr->cr_agroups < oldcred->cr_ngroups) {
+               groups = oldcred->cr_ngroups;
                PROC_UNLOCK(p);
                crextend(cr, groups);
                PROC_LOCK(p);

Reply via email to