Skip to content

Commit bb4f07f

Browse files
palichucklever
authored andcommitted
nfsd: Fix NFSD_MAY_BYPASS_GSS and NFSD_MAY_BYPASS_GSS_ON_ROOT
Currently NFSD_MAY_BYPASS_GSS and NFSD_MAY_BYPASS_GSS_ON_ROOT do not bypass only GSS, but bypass any method. This is a problem specially for NFS3 AUTH_NULL-only exports. The purpose of NFSD_MAY_BYPASS_GSS_ON_ROOT is described in RFC 2623, section 2.3.2, to allow mounting NFS2/3 GSS-only export without authentication. So few procedures which do not expose security risk used during mount time can be called also with AUTH_NONE or AUTH_SYS, to allow client mount operation to finish successfully. The problem with current implementation is that for AUTH_NULL-only exports, the NFSD_MAY_BYPASS_GSS_ON_ROOT is active also for NFS3 AUTH_UNIX mount attempts which confuse NFS3 clients, and make them think that AUTH_UNIX is enabled and is working. Linux NFS3 client never switches from AUTH_UNIX to AUTH_NONE on active mount, which makes the mount inaccessible. Fix the NFSD_MAY_BYPASS_GSS and NFSD_MAY_BYPASS_GSS_ON_ROOT implementation and really allow to bypass only exports which have enabled some real authentication (GSS, TLS, or any other). The result would be: For AUTH_NULL-only export if client attempts to do mount with AUTH_UNIX flavor then it will receive access errors, which instruct client that AUTH_UNIX flavor is not usable and will either try other auth flavor (AUTH_NULL if enabled) or fails mount procedure. Similarly if client attempt to do mount with AUTH_NULL flavor and only AUTH_UNIX flavor is enabled then the client will receive access error. This should fix problems with AUTH_NULL-only or AUTH_UNIX-only exports if client attempts to mount it with other auth flavor (e.g. with AUTH_NULL for AUTH_UNIX-only export, or with AUTH_UNIX for AUTH_NULL-only export). Signed-off-by: Pali Rohár <[email protected]> Reviewed-by: NeilBrown <[email protected]> Signed-off-by: Chuck Lever <[email protected]>
1 parent 6000209 commit bb4f07f

File tree

6 files changed

+31
-8
lines changed

6 files changed

+31
-8
lines changed

fs/nfsd/export.c

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1078,12 +1078,14 @@ static struct svc_export *exp_find(struct cache_detail *cd,
10781078
* check_nfsd_access - check if access to export is allowed.
10791079
* @exp: svc_export that is being accessed.
10801080
* @rqstp: svc_rqst attempting to access @exp (will be NULL for LOCALIO).
1081+
* @may_bypass_gss: reduce strictness of authorization check
10811082
*
10821083
* Return values:
10831084
* %nfs_ok if access is granted, or
10841085
* %nfserr_wrongsec if access is denied
10851086
*/
1086-
__be32 check_nfsd_access(struct svc_export *exp, struct svc_rqst *rqstp)
1087+
__be32 check_nfsd_access(struct svc_export *exp, struct svc_rqst *rqstp,
1088+
bool may_bypass_gss)
10871089
{
10881090
struct exp_flavor_info *f, *end = exp->ex_flavors + exp->ex_nflavors;
10891091
struct svc_xprt *xprt;
@@ -1140,6 +1142,23 @@ __be32 check_nfsd_access(struct svc_export *exp, struct svc_rqst *rqstp)
11401142
if (nfsd4_spo_must_allow(rqstp))
11411143
return nfs_ok;
11421144

1145+
/* Some calls may be processed without authentication
1146+
* on GSS exports. For example NFS2/3 calls on root
1147+
* directory, see section 2.3.2 of rfc 2623.
1148+
* For "may_bypass_gss" check that export has really
1149+
* enabled some flavor with authentication (GSS or any
1150+
* other) and also check that the used auth flavor is
1151+
* without authentication (none or sys).
1152+
*/
1153+
if (may_bypass_gss && (
1154+
rqstp->rq_cred.cr_flavor == RPC_AUTH_NULL ||
1155+
rqstp->rq_cred.cr_flavor == RPC_AUTH_UNIX)) {
1156+
for (f = exp->ex_flavors; f < end; f++) {
1157+
if (f->pseudoflavor >= RPC_AUTH_DES)
1158+
return 0;
1159+
}
1160+
}
1161+
11431162
denied:
11441163
return nfserr_wrongsec;
11451164
}

fs/nfsd/export.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,8 @@ struct svc_expkey {
101101

102102
struct svc_cred;
103103
int nfsexp_flags(struct svc_cred *cred, struct svc_export *exp);
104-
__be32 check_nfsd_access(struct svc_export *exp, struct svc_rqst *rqstp);
104+
__be32 check_nfsd_access(struct svc_export *exp, struct svc_rqst *rqstp,
105+
bool may_bypass_gss);
105106

106107
/*
107108
* Function declarations

fs/nfsd/nfs4proc.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2797,7 +2797,7 @@ nfsd4_proc_compound(struct svc_rqst *rqstp)
27972797

27982798
if (current_fh->fh_export &&
27992799
need_wrongsec_check(rqstp))
2800-
op->status = check_nfsd_access(current_fh->fh_export, rqstp);
2800+
op->status = check_nfsd_access(current_fh->fh_export, rqstp, false);
28012801
}
28022802
encode_op:
28032803
if (op->status == nfserr_replay_me) {

fs/nfsd/nfs4xdr.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3767,7 +3767,7 @@ nfsd4_encode_entry4_fattr(struct nfsd4_readdir *cd, const char *name,
37673767
nfserr = nfserrno(err);
37683768
goto out_put;
37693769
}
3770-
nfserr = check_nfsd_access(exp, cd->rd_rqstp);
3770+
nfserr = check_nfsd_access(exp, cd->rd_rqstp, false);
37713771
if (nfserr)
37723772
goto out_put;
37733773

fs/nfsd/nfsfh.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -320,6 +320,7 @@ __fh_verify(struct svc_rqst *rqstp,
320320
{
321321
struct nfsd_net *nn = net_generic(net, nfsd_net_id);
322322
struct svc_export *exp = NULL;
323+
bool may_bypass_gss = false;
323324
struct dentry *dentry;
324325
__be32 error;
325326

@@ -367,18 +368,20 @@ __fh_verify(struct svc_rqst *rqstp,
367368
* which clients virtually always use auth_sys for,
368369
* even while using RPCSEC_GSS for NFS.
369370
*/
370-
if (access & NFSD_MAY_LOCK || access & NFSD_MAY_BYPASS_GSS)
371+
if (access & NFSD_MAY_LOCK)
371372
goto skip_pseudoflavor_check;
373+
if (access & NFSD_MAY_BYPASS_GSS)
374+
may_bypass_gss = true;
372375
/*
373376
* Clients may expect to be able to use auth_sys during mount,
374377
* even if they use gss for everything else; see section 2.3.2
375378
* of rfc 2623.
376379
*/
377380
if (access & NFSD_MAY_BYPASS_GSS_ON_ROOT
378381
&& exp->ex_path.dentry == dentry)
379-
goto skip_pseudoflavor_check;
382+
may_bypass_gss = true;
380383

381-
error = check_nfsd_access(exp, rqstp);
384+
error = check_nfsd_access(exp, rqstp, may_bypass_gss);
382385
if (error)
383386
goto out;
384387

fs/nfsd/vfs.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ nfsd_lookup(struct svc_rqst *rqstp, struct svc_fh *fhp, const char *name,
321321
err = nfsd_lookup_dentry(rqstp, fhp, name, len, &exp, &dentry);
322322
if (err)
323323
return err;
324-
err = check_nfsd_access(exp, rqstp);
324+
err = check_nfsd_access(exp, rqstp, false);
325325
if (err)
326326
goto out;
327327
/*

0 commit comments

Comments
 (0)