Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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 <pali@kernel.org>
Reviewed-by: NeilBrown <neilb@suse.de>
Signed-off-by: Chuck Lever <chuck.lever@oracle.com>

authored by

Pali Rohár and committed by
Chuck Lever
bb4f07f2 60002092

+31 -8
+20 -1
fs/nfsd/export.c
··· 1078 1078 * check_nfsd_access - check if access to export is allowed. 1079 1079 * @exp: svc_export that is being accessed. 1080 1080 * @rqstp: svc_rqst attempting to access @exp (will be NULL for LOCALIO). 1081 + * @may_bypass_gss: reduce strictness of authorization check 1081 1082 * 1082 1083 * Return values: 1083 1084 * %nfs_ok if access is granted, or 1084 1085 * %nfserr_wrongsec if access is denied 1085 1086 */ 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) 1087 1089 { 1088 1090 struct exp_flavor_info *f, *end = exp->ex_flavors + exp->ex_nflavors; 1089 1091 struct svc_xprt *xprt; ··· 1141 1139 1142 1140 if (nfsd4_spo_must_allow(rqstp)) 1143 1141 return nfs_ok; 1142 + 1143 + /* Some calls may be processed without authentication 1144 + * on GSS exports. For example NFS2/3 calls on root 1145 + * directory, see section 2.3.2 of rfc 2623. 1146 + * For "may_bypass_gss" check that export has really 1147 + * enabled some flavor with authentication (GSS or any 1148 + * other) and also check that the used auth flavor is 1149 + * without authentication (none or sys). 1150 + */ 1151 + if (may_bypass_gss && ( 1152 + rqstp->rq_cred.cr_flavor == RPC_AUTH_NULL || 1153 + rqstp->rq_cred.cr_flavor == RPC_AUTH_UNIX)) { 1154 + for (f = exp->ex_flavors; f < end; f++) { 1155 + if (f->pseudoflavor >= RPC_AUTH_DES) 1156 + return 0; 1157 + } 1158 + } 1144 1159 1145 1160 denied: 1146 1161 return nfserr_wrongsec;
+2 -1
fs/nfsd/export.h
··· 101 101 102 102 struct svc_cred; 103 103 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); 105 106 106 107 /* 107 108 * Function declarations
+1 -1
fs/nfsd/nfs4proc.c
··· 2797 2797 2798 2798 if (current_fh->fh_export && 2799 2799 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); 2801 2801 } 2802 2802 encode_op: 2803 2803 if (op->status == nfserr_replay_me) {
+1 -1
fs/nfsd/nfs4xdr.c
··· 3767 3767 nfserr = nfserrno(err); 3768 3768 goto out_put; 3769 3769 } 3770 - nfserr = check_nfsd_access(exp, cd->rd_rqstp); 3770 + nfserr = check_nfsd_access(exp, cd->rd_rqstp, false); 3771 3771 if (nfserr) 3772 3772 goto out_put; 3773 3773
+6 -3
fs/nfsd/nfsfh.c
··· 320 320 { 321 321 struct nfsd_net *nn = net_generic(net, nfsd_net_id); 322 322 struct svc_export *exp = NULL; 323 + bool may_bypass_gss = false; 323 324 struct dentry *dentry; 324 325 __be32 error; 325 326 ··· 368 367 * which clients virtually always use auth_sys for, 369 368 * even while using RPCSEC_GSS for NFS. 370 369 */ 371 - if (access & NFSD_MAY_LOCK || access & NFSD_MAY_BYPASS_GSS) 370 + if (access & NFSD_MAY_LOCK) 372 371 goto skip_pseudoflavor_check; 372 + if (access & NFSD_MAY_BYPASS_GSS) 373 + may_bypass_gss = true; 373 374 /* 374 375 * Clients may expect to be able to use auth_sys during mount, 375 376 * even if they use gss for everything else; see section 2.3.2 ··· 379 376 */ 380 377 if (access & NFSD_MAY_BYPASS_GSS_ON_ROOT 381 378 && exp->ex_path.dentry == dentry) 382 - goto skip_pseudoflavor_check; 379 + may_bypass_gss = true; 383 380 384 - error = check_nfsd_access(exp, rqstp); 381 + error = check_nfsd_access(exp, rqstp, may_bypass_gss); 385 382 if (error) 386 383 goto out; 387 384
+1 -1
fs/nfsd/vfs.c
··· 321 321 err = nfsd_lookup_dentry(rqstp, fhp, name, len, &exp, &dentry); 322 322 if (err) 323 323 return err; 324 - err = check_nfsd_access(exp, rqstp); 324 + err = check_nfsd_access(exp, rqstp, false); 325 325 if (err) 326 326 goto out; 327 327 /*