NFSD: Handle @rqstp == NULL in check_nfsd_access()
authorNeilBrown <neilb@suse.de>
Thu, 5 Sep 2024 19:09:38 +0000 (15:09 -0400)
committerAnna Schumaker <anna.schumaker@oracle.com>
Mon, 23 Sep 2024 19:03:29 +0000 (15:03 -0400)
LOCALIO-initiated open operations are not running in an nfsd thread
and thus do not have an associated svc_rqst context.

Signed-off-by: NeilBrown <neilb@suse.de>
Co-developed-by: Mike Snitzer <snitzer@kernel.org>
Signed-off-by: Mike Snitzer <snitzer@kernel.org>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
Reviewed-by: Jeff Layton <jlayton@kernel.org>
Signed-off-by: Anna Schumaker <anna.schumaker@oracle.com>
fs/nfsd/export.c

index 7bb4f2075ac5bcbb07f1f02bb8a5b62df03e04aa..c82d8e3e0d4f28a7a6b702310579026559badd1a 100644 (file)
@@ -1074,10 +1074,30 @@ static struct svc_export *exp_find(struct cache_detail *cd,
        return exp;
 }
 
+/**
+ * check_nfsd_access - check if access to export is allowed.
+ * @exp: svc_export that is being accessed.
+ * @rqstp: svc_rqst attempting to access @exp (will be NULL for LOCALIO).
+ *
+ * Return values:
+ *   %nfs_ok if access is granted, or
+ *   %nfserr_wrongsec if access is denied
+ */
 __be32 check_nfsd_access(struct svc_export *exp, struct svc_rqst *rqstp)
 {
        struct exp_flavor_info *f, *end = exp->ex_flavors + exp->ex_nflavors;
-       struct svc_xprt *xprt = rqstp->rq_xprt;
+       struct svc_xprt *xprt;
+
+       /*
+        * If rqstp is NULL, this is a LOCALIO request which will only
+        * ever use a filehandle/credential pair for which access has
+        * been affirmed (by ACCESS or OPEN NFS requests) over the
+        * wire. So there is no need for further checks here.
+        */
+       if (!rqstp)
+               return nfs_ok;
+
+       xprt = rqstp->rq_xprt;
 
        if (exp->ex_xprtsec_modes & NFSEXP_XPRTSEC_NONE) {
                if (!test_bit(XPT_TLS_SESSION, &xprt->xpt_flags))
@@ -1098,17 +1118,17 @@ __be32 check_nfsd_access(struct svc_export *exp, struct svc_rqst *rqstp)
 ok:
        /* legacy gss-only clients are always OK: */
        if (exp->ex_client == rqstp->rq_gssclient)
-               return 0;
+               return nfs_ok;
        /* ip-address based client; check sec= export option: */
        for (f = exp->ex_flavors; f < end; f++) {
                if (f->pseudoflavor == rqstp->rq_cred.cr_flavor)
-                       return 0;
+                       return nfs_ok;
        }
        /* defaults in absence of sec= options: */
        if (exp->ex_nflavors == 0) {
                if (rqstp->rq_cred.cr_flavor == RPC_AUTH_NULL ||
                    rqstp->rq_cred.cr_flavor == RPC_AUTH_UNIX)
-                       return 0;
+                       return nfs_ok;
        }
 
        /* If the compound op contains a spo_must_allowed op,
@@ -1118,7 +1138,7 @@ ok:
         */
 
        if (nfsd4_spo_must_allow(rqstp))
-               return 0;
+               return nfs_ok;
 
 denied:
        return nfserr_wrongsec;