From 9297f16a23f27234573a606605895683c8cd626c Mon Sep 17 00:00:00 2001 From: rmacklem Date: Fri, 3 May 2019 02:30:01 +0000 Subject: [PATCH] MFC: r346365 Fix the NFSv4.0 server so that it does not support NFSv4.1 attributes. During inspection of a packet trace, I noticed that an NFSv4.0 mount reported that it supported attributes that are only defined for NFSv4.1. In practice, this bug appears to be benign, since NFSv4.0 clients will not use attributes that were added for NFSv4.1. However, this was not correct and this patch fixes the NFSv4.0 server so that it only supports attributes defined for NFSv4.0. It also adds a definition for NFSv4.1 attributes that can only be set, although it is only defined as 0 for now. This is anticipation of the addition of support for the NFSv4.1 mode+mask attribute soon. git-svn-id: svn://svn.freebsd.org/base/stable/10@347040 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f --- sys/fs/nfs/nfs.h | 20 +++++++++++++++----- sys/fs/nfs/nfs_commonsubs.c | 16 ++++++++-------- sys/fs/nfs/nfsproto.h | 18 +++++++++++++++--- sys/fs/nfsserver/nfs_nfsdport.c | 2 +- 4 files changed, 39 insertions(+), 17 deletions(-) diff --git a/sys/fs/nfs/nfs.h b/sys/fs/nfs/nfs.h index e2066a4fe..cc52856cd 100644 --- a/sys/fs/nfs/nfs.h +++ b/sys/fs/nfs/nfs.h @@ -383,10 +383,14 @@ typedef struct { (t)->bits[2] = (f)->bits[2]; \ } while (0) -#define NFSSETSUPP_ATTRBIT(b) do { \ +#define NFSSETSUPP_ATTRBIT(b, n) do { \ (b)->bits[0] = NFSATTRBIT_SUPP0; \ - (b)->bits[1] = (NFSATTRBIT_SUPP1 | NFSATTRBIT_SUPPSETONLY); \ - (b)->bits[2] = NFSATTRBIT_SUPP2; \ + (b)->bits[1] = (NFSATTRBIT_SUPP1 | NFSATTRBIT_SUPPSETONLY1); \ + (b)->bits[2] = (NFSATTRBIT_SUPP2 | NFSATTRBIT_SUPPSETONLY2); \ + if (((n)->nd_flag & ND_NFSV41) == 0) { \ + (b)->bits[1] &= ~NFSATTRBIT_NFSV41_1; \ + (b)->bits[2] &= ~NFSATTRBIT_NFSV41_2; \ + } \ } while (0) #define NFSISSET_ATTRBIT(b, p) ((b)->bits[(p) / 32] & (1 << ((p) % 32))) @@ -405,16 +409,22 @@ typedef struct { (b)->bits[2] &= ((a)->bits[2]); \ } while (0) -#define NFSCLRNOTFILLABLE_ATTRBIT(b) do { \ +#define NFSCLRNOTFILLABLE_ATTRBIT(b, n) do { \ (b)->bits[0] &= NFSATTRBIT_SUPP0; \ (b)->bits[1] &= NFSATTRBIT_SUPP1; \ (b)->bits[2] &= NFSATTRBIT_SUPP2; \ + if (((n)->nd_flag & ND_NFSV41) == 0) { \ + (b)->bits[1] &= ~NFSATTRBIT_NFSV41_1; \ + (b)->bits[2] &= ~NFSATTRBIT_NFSV41_2; \ + } \ } while (0) -#define NFSCLRNOTSETABLE_ATTRBIT(b) do { \ +#define NFSCLRNOTSETABLE_ATTRBIT(b, n) do { \ (b)->bits[0] &= NFSATTRBIT_SETABLE0; \ (b)->bits[1] &= NFSATTRBIT_SETABLE1; \ (b)->bits[2] &= NFSATTRBIT_SETABLE2; \ + if (((n)->nd_flag & ND_NFSV41) == 0) \ + (b)->bits[2] &= ~NFSATTRBIT_NFSV41_2; \ } while (0) #define NFSNONZERO_ATTRBIT(b) ((b)->bits[0] || (b)->bits[1] || (b)->bits[2]) diff --git a/sys/fs/nfs/nfs_commonsubs.c b/sys/fs/nfs/nfs_commonsubs.c index 18fd55d2b..7924fadd4 100644 --- a/sys/fs/nfs/nfs_commonsubs.c +++ b/sys/fs/nfs/nfs_commonsubs.c @@ -927,7 +927,7 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, if (error) goto nfsmout; if (compare && !(*retcmpp)) { - NFSSETSUPP_ATTRBIT(&checkattrbits); + NFSSETSUPP_ATTRBIT(&checkattrbits, nd); if (!NFSEQUAL_ATTRBIT(&retattrbits, &checkattrbits) || retnotsup) *retcmpp = NFSERR_NOTSAME; @@ -1778,8 +1778,8 @@ nfsv4_loadattr(struct nfsrv_descript *nd, vnode_t vp, if (error) goto nfsmout; if (compare && !(*retcmpp)) { - NFSSETSUPP_ATTRBIT(&checkattrbits); - NFSCLRNOTSETABLE_ATTRBIT(&checkattrbits); + NFSSETSUPP_ATTRBIT(&checkattrbits, nd); + NFSCLRNOTSETABLE_ATTRBIT(&checkattrbits, nd); NFSCLRBIT_ATTRBIT(&checkattrbits, NFSATTRBIT_TIMEACCESSSET); if (!NFSEQUAL_ATTRBIT(&retattrbits, &checkattrbits) @@ -2074,10 +2074,10 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp, * reply call. */ if (p == NULL && cred == NULL) { - NFSCLRNOTSETABLE_ATTRBIT(retbitp); + NFSCLRNOTSETABLE_ATTRBIT(retbitp, nd); aclp = saclp; } else { - NFSCLRNOTFILLABLE_ATTRBIT(retbitp); + NFSCLRNOTFILLABLE_ATTRBIT(retbitp, nd); naclp = acl_alloc(M_WAITOK); aclp = naclp; } @@ -2143,7 +2143,7 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp, if (NFSISSET_ATTRBIT(retbitp, bitpos)) { switch (bitpos) { case NFSATTRBIT_SUPPORTEDATTRS: - NFSSETSUPP_ATTRBIT(&attrbits); + NFSSETSUPP_ATTRBIT(&attrbits, nd); if (nfsrv_useacl == 0 || ((cred != NULL || p != NULL) && supports_nfsv4acls == 0)) { NFSCLRBIT_ATTRBIT(&attrbits,NFSATTRBIT_ACLSUPPORT); @@ -2525,8 +2525,8 @@ nfsv4_fillattr(struct nfsrv_descript *nd, struct mount *mp, vnode_t vp, retnum += NFSX_HYPER; break; case NFSATTRBIT_SUPPATTREXCLCREAT: - NFSSETSUPP_ATTRBIT(&attrbits); - NFSCLRNOTSETABLE_ATTRBIT(&attrbits); + NFSSETSUPP_ATTRBIT(&attrbits, nd); + NFSCLRNOTSETABLE_ATTRBIT(&attrbits, nd); NFSCLRBIT_ATTRBIT(&attrbits, NFSATTRBIT_TIMEACCESSSET); retnum += nfsrv_putattrbit(nd, &attrbits); break; diff --git a/sys/fs/nfs/nfsproto.h b/sys/fs/nfs/nfsproto.h index 6c61def6f..96fa6c3e0 100644 --- a/sys/fs/nfs/nfsproto.h +++ b/sys/fs/nfs/nfsproto.h @@ -1049,11 +1049,11 @@ struct nfsv3_sattr { #define NFSATTRBIT_SUPP2 NFSATTRBM_SUPPATTREXCLCREAT /* - * NFSATTRBIT_SUPPSETONLY is the OR of NFSATTRBIT_TIMEACCESSSET and - * NFSATTRBIT_TIMEMODIFYSET. + * These are the set only attributes. */ -#define NFSATTRBIT_SUPPSETONLY (NFSATTRBM_TIMEACCESSSET | \ +#define NFSATTRBIT_SUPPSETONLY1 (NFSATTRBM_TIMEACCESSSET | \ NFSATTRBM_TIMEMODIFYSET) +#define NFSATTRBIT_SUPPSETONLY2 0 /* * NFSATTRBIT_SETABLE - SETABLE0 - bits 0<->31 @@ -1071,6 +1071,18 @@ struct nfsv3_sattr { NFSATTRBM_TIMEMODIFYSET) #define NFSATTRBIT_SETABLE2 0 +/* + * NFSATTRBIT_NFSV41 - Attributes only supported by NFSv4.1. + */ +#define NFSATTRBIT_NFSV41_1 \ + (NFSATTRBM_FSLAYOUTTYPE) +#define NFSATTRBIT_NFSV41_2 \ + (NFSATTRBM_LAYOUTTYPE | \ + NFSATTRBM_LAYOUTBLKSIZE | \ + NFSATTRBM_LAYOUTALIGNMENT | \ + NFSATTRBM_MODESETMASKED | \ + NFSATTRBM_SUPPATTREXCLCREAT) + /* * Set of attributes that the getattr vnode op needs. * OR of the following bits. diff --git a/sys/fs/nfsserver/nfs_nfsdport.c b/sys/fs/nfsserver/nfs_nfsdport.c index 7460bf06b..318a51dd6 100644 --- a/sys/fs/nfsserver/nfs_nfsdport.c +++ b/sys/fs/nfsserver/nfs_nfsdport.c @@ -1863,7 +1863,7 @@ nfsrvd_readdirplus(struct nfsrv_descript *nd, int isdgram, if (error) goto nfsmout; NFSSET_ATTRBIT(&savbits, &attrbits); - NFSCLRNOTFILLABLE_ATTRBIT(&attrbits); + NFSCLRNOTFILLABLE_ATTRBIT(&attrbits, nd); NFSZERO_ATTRBIT(&rderrbits); NFSSETBIT_ATTRBIT(&rderrbits, NFSATTRBIT_RDATTRERROR); } else { -- 2.45.0