The branch stable/13 has been updated by olce:

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

commit 29a0511b184d6d59c6b0fee72dd6f48e6b8d0081
Author:     Olivier Certner <o...@freebsd.org>
AuthorDate: 2024-10-08 09:21:17 +0000
Commit:     Olivier Certner <o...@freebsd.org>
CommitDate: 2025-01-17 12:24:51 +0000

    mountd(8): parsecred(): Fallback to "nogroup" or GID_NOGROUP
    
    In the 'uid:gid:gid:...' case (for '-maproot' or '-mapall'), if no GID
    is specified at all (i.e., input is of the form 'uid:', with the colon
    at the end), mountd(8) would pass credentials with an empty array of
    groups to the kernel.
    
    For security reasons, we have put in place a kernel fallback a while
    ago, which is to use the single group GID_NOGROUP (see commits
    cfbe7a62dc62 ("nfs, rpc: Ensure kernel credentials have at least one
    group") and 5169d4307eb9 ("nfs: Fallback to GID_NOGROUP on no groups")).
    Here, as we are in userland, we first try to find the GID number
    corresponding to "nogroup", and only then fall back to GID_NOGROUP, as
    nfsuserd(8) does.
    
    Approved by:    markj (mentor)
    MFC after:      2 weeks
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D47011
    
    (cherry picked from commit bdc259ef382f76b1821d4356049d5b856c42901a)
---
 usr.sbin/mountd/mountd.c | 27 +++++++++++++++++++++++++--
 1 file changed, 25 insertions(+), 2 deletions(-)

diff --git a/usr.sbin/mountd/mountd.c b/usr.sbin/mountd/mountd.c
index ebd88d3fdd66..6b3a9af1c279 100644
--- a/usr.sbin/mountd/mountd.c
+++ b/usr.sbin/mountd/mountd.c
@@ -273,6 +273,8 @@ static int  xdr_mlist(XDR *, caddr_t);
 static void    terminate(int);
 static void    cp_cred(struct expcred *, struct expcred *);
 
+static gid_t   nogroup();
+
 #define        EXPHASH(f)      (fnv_32_buf((f), sizeof(fsid_t), 0) % 
exphashsize)
 static struct exportlisthead *exphead = NULL;
 static struct exportlisthead *oldexphead = NULL;
@@ -1577,7 +1579,7 @@ get_exportlist_one(int passno)
                anon.cr_groups = anon.cr_smallgrps;
                anon.cr_uid = UID_NOBODY;
                anon.cr_ngroups = 1;
-               anon.cr_groups[0] = GID_NOGROUP;
+               anon.cr_groups[0] = nogroup();
                exflags = MNT_EXPORTED;
                got_nondir = 0;
                opt_flags = 0;
@@ -3582,7 +3584,7 @@ parsecred(char *namelist, struct expcred *cr)
         */
        cr->cr_groups = cr->cr_smallgrps;
        cr->cr_uid = UID_NOBODY;
-       cr->cr_groups[0] = GID_NOGROUP;
+       cr->cr_groups[0] = nogroup();
        cr->cr_ngroups = 1;
        /*
         * Get the user's password table entry.
@@ -3651,6 +3653,11 @@ parsecred(char *namelist, struct expcred *cr)
                }
                groups[cr->cr_ngroups++] = group;
        }
+       if (cr->cr_ngroups == 0) {
+               /* cr->cr_groups[0] filled at start with nogroup(). */
+               cr->cr_ngroups = 1;
+               return;
+       }
        if (cr->cr_ngroups > SMALLNGROUPS)
                cr->cr_groups = malloc(cr->cr_ngroups * sizeof(gid_t));
        memcpy(cr->cr_groups, groups, cr->cr_ngroups * sizeof(gid_t));
@@ -3989,3 +3996,19 @@ cp_cred(struct expcred *outcr, struct expcred *incr)
        memcpy(outcr->cr_groups, incr->cr_groups, incr->cr_ngroups *
            sizeof(gid_t));
 }
+
+static gid_t
+nogroup()
+{
+       static gid_t nogroup = 0;       /* 0 means unset. */
+
+       if (nogroup == 0) {
+               const struct group *gr = getgrnam("nogroup");
+
+               if (gr != NULL && gr->gr_gid != 0)
+                       nogroup = gr->gr_gid;
+               else
+                       nogroup = GID_NOGROUP;
+       }
+       return (nogroup);
+}

Reply via email to