FAILED: patch "[PATCH] NFSD: fix endianness issue in nfsd4_encode_fattr4" failed to apply to 6.8-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 6.8-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.8.y
git checkout FETCH_HEAD
git cherry-pick -x f488138b526715c6d2568d7329c4477911be4210
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2024041908-sandblast-sullen-2eed@gregkh' --subject-prefix 'PATCH 6.8.y' HEAD^..
Possible dependencies:
f488138b5267 ("NFSD: fix endianness issue in nfsd4_encode_fattr4") c5967721e106 ("NFSD: handle GETATTR conflict with write delegation") 6487a13b5c6b ("NFSD: add support for CB_GETATTR callback") 4b14885411f7 ("nfsd: make all of the nfsd stats per-network namespace") 93483ac5fec6 ("nfsd: expose /proc/net/sunrpc/nfsd in net namespaces") d98416cc2154 ("nfsd: rename NFSD_NET_* to NFSD_STATS_*")
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From f488138b526715c6d2568d7329c4477911be4210 Mon Sep 17 00:00:00 2001
From: Vasily Gorbik <[email protected]>
Date: Thu, 11 Apr 2024 11:45:57 +0200
Subject: [PATCH] NFSD: fix endianness issue in nfsd4_encode_fattr4
The nfs4 mount fails with EIO on 64-bit big endian architectures since v6.7. The issue arises from employing a union in the nfsd4_encode_fattr4() function to overlay a 32-bit array with a 64-bit values based bitmap, which does not function as intended. Address the endianness issue by utilizing bitmap_from_arr32() to copy 32-bit attribute masks into a bitmap in an endianness-agnostic manner.
fs/nfsd/nfs4xdr.c +23 -24
@@ -3490,11 +3490,13 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr, struct dentry *dentry, const u32 *bmval, int ignore_crossmnt) { +DECLARE_BITMAP (attr_bitmap ,ARRAY_SIZE (nfsd4_enc_fattr4_encode_ops ));struct nfsd4_fattr_args args;struct svc_fh *tempfh =NULL ;int starting_len = xdr->buf->len;__be32 *attrlen_p, status;int attrlen_offset; +u32 attrmask[3 ];int err;struct nfsd4_compoundres *resp = rqstp->rq_resp;u32 minorversion = resp->cstate.minorversion;
@@ -3502,10 +3504,6 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr, .mnt = exp->ex_path.mnt, .dentry = dentry, }; -union { -u32 attrmask[3 ]; -unsigned long mask[2 ]; - } u;unsigned long bit;bool file_modified = false;u64 size =0 ;
@@ -3521,20 +3519,19 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,/* * Make a local copy of the attribute bitmap that can be modified. */ -memset (&u,0 ,sizeof (u)); - u.attrmask[0 ] = bmval[0 ]; - u.attrmask[1 ] = bmval[1 ]; - u.attrmask[2 ] = bmval[2 ]; + attrmask[0 ] = bmval[0 ]; + attrmask[1 ] = bmval[1 ]; + attrmask[2 ] = bmval[2 ]; args.rdattr_err =0 ;if (exp->ex_fslocs.migrated) { - status =fattr_handle_absent_fs (&u.attrmask[0 ], &u.attrmask[1 ], - &u.attrmask[2 ], &args.rdattr_err); + status =fattr_handle_absent_fs (&attrmask[0 ], &attrmask[1 ], + &attrmask[2 ], &args.rdattr_err);if (status) goto out; } args.size =0 ; -if (u.attrmask[0 ] & (FATTR4_WORD0_CHANGE |FATTR4_WORD0_SIZE )) { +if (attrmask[0 ] & (FATTR4_WORD0_CHANGE |FATTR4_WORD0_SIZE )) { status =nfsd4_deleg_getattr_conflict (rqstp,d_inode (dentry), &file_modified, &size);if (status)
@@ -3553,16 +3550,16 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,if (!(args.stat.result_mask &STATX_BTIME ))/* underlying FS does not offer btime so we can't share it */ - u.attrmask[1 ] &= ~FATTR4_WORD1_TIME_CREATE ; -if ((u.attrmask[0 ] & (FATTR4_WORD0_FILES_AVAIL |FATTR4_WORD0_FILES_FREE | + attrmask[1 ] &= ~FATTR4_WORD1_TIME_CREATE ; +if ((attrmask[0 ] & (FATTR4_WORD0_FILES_AVAIL |FATTR4_WORD0_FILES_FREE |FATTR4_WORD0_FILES_TOTAL |FATTR4_WORD0_MAXNAME )) || - (u.attrmask[1 ] & (FATTR4_WORD1_SPACE_AVAIL |FATTR4_WORD1_SPACE_FREE | + (attrmask[1 ] & (FATTR4_WORD1_SPACE_AVAIL |FATTR4_WORD1_SPACE_FREE |FATTR4_WORD1_SPACE_TOTAL ))) { err =vfs_statfs (&path, &args.statfs);if (err) goto out_nfserr; } -if ((u.attrmask[0 ] & (FATTR4_WORD0_FILEHANDLE |FATTR4_WORD0_FSID )) && +if ((attrmask[0 ] & (FATTR4_WORD0_FILEHANDLE |FATTR4_WORD0_FSID )) && !fhp) { tempfh =kmalloc (sizeof (struct svc_fh ),GFP_KERNEL ); status = nfserr_jukebox;
@@ -3577,10 +3574,10 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr, args.fhp = fhp; args.acl =NULL ; -if (u.attrmask[0 ] &FATTR4_WORD0_ACL ) { +if (attrmask[0 ] &FATTR4_WORD0_ACL ) { err =nfsd4_get_nfs4_acl (rqstp, dentry, &args.acl);if (err == -EOPNOTSUPP ) - u.attrmask[0 ] &= ~FATTR4_WORD0_ACL ; + attrmask[0 ] &= ~FATTR4_WORD0_ACL ;else if (err == -EINVAL ) { status = nfserr_attrnotsupp; goto out;
@@ -3592,17 +3589,17 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,#ifdef CONFIG_NFSD_V4_SECURITY_LABEL args.context =NULL ; -if ((u.attrmask[2 ] &FATTR4_WORD2_SECURITY_LABEL ) || - u.attrmask[0 ] &FATTR4_WORD0_SUPPORTED_ATTRS ) { +if ((attrmask[2 ] &FATTR4_WORD2_SECURITY_LABEL ) || + attrmask[0 ] &FATTR4_WORD0_SUPPORTED_ATTRS ) {if (exp->ex_flags &NFSEXP_SECURITY_LABEL ) err =security_inode_getsecctx (d_inode (dentry), &args.context, &args.contextlen);else err = -EOPNOTSUPP ; args.contextsupport = (err ==0 ); -if (u.attrmask[2 ] &FATTR4_WORD2_SECURITY_LABEL ) { +if (attrmask[2 ] &FATTR4_WORD2_SECURITY_LABEL ) {if (err == -EOPNOTSUPP ) - u.attrmask[2 ] &= ~FATTR4_WORD2_SECURITY_LABEL ; + attrmask[2 ] &= ~FATTR4_WORD2_SECURITY_LABEL ;else if (err) goto out_nfserr; }
@@ -3610,8 +3607,8 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,#endif /* CONFIG_NFSD_V4_SECURITY_LABEL */ /* attrmask */ - status =nfsd4_encode_bitmap4 (xdr, u.attrmask[0 ], - u.attrmask[1 ], u.attrmask[2 ]); + status =nfsd4_encode_bitmap4 (xdr, attrmask[0 ], attrmask[1 ], + attrmask[2 ]);if (status) goto out;
@@ -3620,7 +3617,9 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr, attrlen_p =xdr_reserve_space (xdr,XDR_UNIT );if (!attrlen_p) goto out_resource; -for_each_set_bit (bit, (const unsigned long *)&u.mask, +bitmap_from_arr32 (attr_bitmap, attrmask, +ARRAY_SIZE (nfsd4_enc_fattr4_encode_ops)); +for_each_set_bit (bit, attr_bitmap,ARRAY_SIZE (nfsd4_enc_fattr4_encode_ops)) { status = nfsd4_enc_fattr4_encode_ops[bit](xdr, &args);if (status != nfs_ok)
[email protected]
maintainerPATCH 1/1 NFSD: fix endianness issue in nfsd4_encode_fattr4
From: Vasily Gorbik <[email protected]>
[ Upstream commit 862bee84d77fa01cc8929656ae77781abf917863 ]
The nfs4 mount fails with EIO on 64-bit big endian architectures since v6.7. The issue arises from employing a union in the nfsd4_encode_fattr4() function to overlay a 32-bit array with a 64-bit values based bitmap, which does not function as intended. Address the endianness issue by utilizing bitmap_from_arr32() to copy 32-bit attribute masks into a bitmap in an endianness-agnostic manner.
--- fs/nfsd/nfs4xdr.c | 47 +++++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 24 deletions(-)
fs/nfsd/nfs4xdr.c +23 -24
@@ -3490,11 +3490,13 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr, struct dentry *dentry, const u32 *bmval, int ignore_crossmnt) { +DECLARE_BITMAP (attr_bitmap ,ARRAY_SIZE (nfsd4_enc_fattr4_encode_ops ));struct nfsd4_fattr_args args;struct svc_fh *tempfh =NULL ;int starting_len = xdr->buf->len;__be32 *attrlen_p, status;int attrlen_offset; +u32 attrmask[3 ];int err;struct nfsd4_compoundres *resp = rqstp->rq_resp;u32 minorversion = resp->cstate.minorversion;
@@ -3502,10 +3504,6 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr, .mnt = exp->ex_path.mnt, .dentry = dentry, }; -union { -u32 attrmask[3 ]; -unsigned long mask[2 ]; - } u;unsigned long bit;WARN_ON_ONCE (bmval[1 ] &NFSD_WRITEONLY_ATTRS_WORD1 );
@@ -3519,20 +3517,19 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,/* * Make a local copy of the attribute bitmap that can be modified. */ -memset (&u,0 ,sizeof (u)); - u.attrmask[0 ] = bmval[0 ]; - u.attrmask[1 ] = bmval[1 ]; - u.attrmask[2 ] = bmval[2 ]; + attrmask[0 ] = bmval[0 ]; + attrmask[1 ] = bmval[1 ]; + attrmask[2 ] = bmval[2 ]; args.rdattr_err =0 ;if (exp->ex_fslocs.migrated) { - status =fattr_handle_absent_fs (&u.attrmask[0 ], &u.attrmask[1 ], - &u.attrmask[2 ], &args.rdattr_err); + status =fattr_handle_absent_fs (&attrmask[0 ], &attrmask[1 ], + &attrmask[2 ], &args.rdattr_err);if (status) goto out; } args.size =0 ; -if (u.attrmask[0 ] & (FATTR4_WORD0_CHANGE |FATTR4_WORD0_SIZE )) { +if (attrmask[0 ] & (FATTR4_WORD0_CHANGE |FATTR4_WORD0_SIZE )) { status =nfsd4_deleg_getattr_conflict (rqstp,d_inode (dentry));if (status) goto out;
@@ -3547,16 +3544,16 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,if (!(args.stat.result_mask &STATX_BTIME ))/* underlying FS does not offer btime so we can't share it */ - u.attrmask[1 ] &= ~FATTR4_WORD1_TIME_CREATE ; -if ((u.attrmask[0 ] & (FATTR4_WORD0_FILES_AVAIL |FATTR4_WORD0_FILES_FREE | + attrmask[1 ] &= ~FATTR4_WORD1_TIME_CREATE ; +if ((attrmask[0 ] & (FATTR4_WORD0_FILES_AVAIL |FATTR4_WORD0_FILES_FREE |FATTR4_WORD0_FILES_TOTAL |FATTR4_WORD0_MAXNAME )) || - (u.attrmask[1 ] & (FATTR4_WORD1_SPACE_AVAIL |FATTR4_WORD1_SPACE_FREE | + (attrmask[1 ] & (FATTR4_WORD1_SPACE_AVAIL |FATTR4_WORD1_SPACE_FREE |FATTR4_WORD1_SPACE_TOTAL ))) { err =vfs_statfs (&path, &args.statfs);if (err) goto out_nfserr; } -if ((u.attrmask[0 ] & (FATTR4_WORD0_FILEHANDLE |FATTR4_WORD0_FSID )) && +if ((attrmask[0 ] & (FATTR4_WORD0_FILEHANDLE |FATTR4_WORD0_FSID )) && !fhp) { tempfh =kmalloc (sizeof (struct svc_fh ),GFP_KERNEL ); status = nfserr_jukebox;
@@ -3571,10 +3568,10 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr, args.fhp = fhp; args.acl =NULL ; -if (u.attrmask[0 ] &FATTR4_WORD0_ACL ) { +if (attrmask[0 ] &FATTR4_WORD0_ACL ) { err =nfsd4_get_nfs4_acl (rqstp, dentry, &args.acl);if (err == -EOPNOTSUPP ) - u.attrmask[0 ] &= ~FATTR4_WORD0_ACL ; + attrmask[0 ] &= ~FATTR4_WORD0_ACL ;else if (err == -EINVAL ) { status = nfserr_attrnotsupp; goto out;
@@ -3586,17 +3583,17 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,#ifdef CONFIG_NFSD_V4_SECURITY_LABEL args.context =NULL ; -if ((u.attrmask[2 ] &FATTR4_WORD2_SECURITY_LABEL ) || - u.attrmask[0 ] &FATTR4_WORD0_SUPPORTED_ATTRS ) { +if ((attrmask[2 ] &FATTR4_WORD2_SECURITY_LABEL ) || + attrmask[0 ] &FATTR4_WORD0_SUPPORTED_ATTRS ) {if (exp->ex_flags &NFSEXP_SECURITY_LABEL ) err =security_inode_getsecctx (d_inode (dentry), &args.context, &args.contextlen);else err = -EOPNOTSUPP ; args.contextsupport = (err ==0 ); -if (u.attrmask[2 ] &FATTR4_WORD2_SECURITY_LABEL ) { +if (attrmask[2 ] &FATTR4_WORD2_SECURITY_LABEL ) {if (err == -EOPNOTSUPP ) - u.attrmask[2 ] &= ~FATTR4_WORD2_SECURITY_LABEL ; + attrmask[2 ] &= ~FATTR4_WORD2_SECURITY_LABEL ;else if (err) goto out_nfserr; }
@@ -3604,8 +3601,8 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,#endif /* CONFIG_NFSD_V4_SECURITY_LABEL */ /* attrmask */ - status =nfsd4_encode_bitmap4 (xdr, u.attrmask[0 ], - u.attrmask[1 ], u.attrmask[2 ]); + status =nfsd4_encode_bitmap4 (xdr, attrmask[0 ], attrmask[1 ], + attrmask[2 ]);if (status) goto out;
@@ -3614,7 +3611,9 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr, attrlen_p =xdr_reserve_space (xdr,XDR_UNIT );if (!attrlen_p) goto out_resource; -for_each_set_bit (bit, (const unsigned long *)&u.mask, +bitmap_from_arr32 (attr_bitmap, attrmask, +ARRAY_SIZE (nfsd4_enc_fattr4_encode_ops)); +for_each_set_bit (bit, attr_bitmap,ARRAY_SIZE (nfsd4_enc_fattr4_encode_ops)) { status = nfsd4_enc_fattr4_encode_ops[bit](xdr, &args);if (status != nfs_ok)
Signature · 1 line
2.43.0
Greg KH
maintainerRe: [PATCH 6.8.y] NFSD: fix endianness issue in nfsd4_encode_fattr4
Quoted 3 lines · On Fri, Apr 19, 2024 at 12:03:15PM -0400, [email protected] wrote:
From: Vasily Gorbik <[email protected]>
[ Upstream commit
862bee84d77fa01cc8929656ae77781abf917863]
that commit is in 6.7, so why would we need to add it to 6.8?
confused,
greg k-h
Re: [PATCH 6.8.y] NFSD: fix endianness issue in nfsd4_encode_fattr4
Quoted 10 lines · Greg KH
Quoted 3 lines · On Fri, Apr 19, 2024 at 12:03:15PM -0400, [email protected] wrote:
From: Vasily Gorbik <[email protected]>
[ Upstream commit
862bee84d77fa01cc8929656ae77781abf917863]that commit is in 6.7, so why would we need to add it to 6.8?
Copy-paste error. Try f488138b526715c6d2568d7329c4477911be4210 instead.
--
Chuck Lever
Greg KH
maintainerRe: [PATCH 6.8.y] NFSD: fix endianness issue in nfsd4_encode_fattr4
Quoted 5 lines · Chuck Lever III
Quoted 5 lines · Greg KH
On Fri, Apr 19, 2024 at 12:03:15PM -0400, [email protected] wrote:
Quoted 8 lines
Quoted 5 lines
Quoted 3 lines
From: Vasily Gorbik <[email protected]>
[ Upstream commit
862bee84d77fa01cc8929656ae77781abf917863]that commit is in 6.7, so why would we need to add it to 6.8?
Copy-paste error. Try
f488138b526715c6d2568d7329c4477911be4210instead.
Can it be sent with the correct one so I don't have to hand-edit this?
thanks,
greg k-h
[email protected]
maintainerPATCH 1/1 NFSD: fix endianness issue in nfsd4_encode_fattr4
In reply to [email protected]From: Vasily Gorbik <[email protected]>
[ Upstream commit f488138b526715c6d2568d7329c4477911be4210 ]
The nfs4 mount fails with EIO on 64-bit big endian architectures since v6.7. The issue arises from employing a union in the nfsd4_encode_fattr4() function to overlay a 32-bit array with a 64-bit values based bitmap, which does not function as intended. Address the endianness issue by utilizing bitmap_from_arr32() to copy 32-bit attribute masks into a bitmap in an endianness-agnostic manner.
--- fs/nfsd/nfs4xdr.c | 47 +++++++++++++++++++++++------------------------ 1 file changed, 23 insertions(+), 24 deletions(-)
fs/nfsd/nfs4xdr.c +23 -24
@@ -3490,11 +3490,13 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr, struct dentry *dentry, const u32 *bmval, int ignore_crossmnt) { +DECLARE_BITMAP (attr_bitmap ,ARRAY_SIZE (nfsd4_enc_fattr4_encode_ops ));struct nfsd4_fattr_args args;struct svc_fh *tempfh =NULL ;int starting_len = xdr->buf->len;__be32 *attrlen_p, status;int attrlen_offset; +u32 attrmask[3 ];int err;struct nfsd4_compoundres *resp = rqstp->rq_resp;u32 minorversion = resp->cstate.minorversion;
@@ -3502,10 +3504,6 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr, .mnt = exp->ex_path.mnt, .dentry = dentry, }; -union { -u32 attrmask[3 ]; -unsigned long mask[2 ]; - } u;unsigned long bit;WARN_ON_ONCE (bmval[1 ] &NFSD_WRITEONLY_ATTRS_WORD1 );
@@ -3519,20 +3517,19 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,/* * Make a local copy of the attribute bitmap that can be modified. */ -memset (&u,0 ,sizeof (u)); - u.attrmask[0 ] = bmval[0 ]; - u.attrmask[1 ] = bmval[1 ]; - u.attrmask[2 ] = bmval[2 ]; + attrmask[0 ] = bmval[0 ]; + attrmask[1 ] = bmval[1 ]; + attrmask[2 ] = bmval[2 ]; args.rdattr_err =0 ;if (exp->ex_fslocs.migrated) { - status =fattr_handle_absent_fs (&u.attrmask[0 ], &u.attrmask[1 ], - &u.attrmask[2 ], &args.rdattr_err); + status =fattr_handle_absent_fs (&attrmask[0 ], &attrmask[1 ], + &attrmask[2 ], &args.rdattr_err);if (status) goto out; } args.size =0 ; -if (u.attrmask[0 ] & (FATTR4_WORD0_CHANGE |FATTR4_WORD0_SIZE )) { +if (attrmask[0 ] & (FATTR4_WORD0_CHANGE |FATTR4_WORD0_SIZE )) { status =nfsd4_deleg_getattr_conflict (rqstp,d_inode (dentry));if (status) goto out;
@@ -3547,16 +3544,16 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,if (!(args.stat.result_mask &STATX_BTIME ))/* underlying FS does not offer btime so we can't share it */ - u.attrmask[1 ] &= ~FATTR4_WORD1_TIME_CREATE ; -if ((u.attrmask[0 ] & (FATTR4_WORD0_FILES_AVAIL |FATTR4_WORD0_FILES_FREE | + attrmask[1 ] &= ~FATTR4_WORD1_TIME_CREATE ; +if ((attrmask[0 ] & (FATTR4_WORD0_FILES_AVAIL |FATTR4_WORD0_FILES_FREE |FATTR4_WORD0_FILES_TOTAL |FATTR4_WORD0_MAXNAME )) || - (u.attrmask[1 ] & (FATTR4_WORD1_SPACE_AVAIL |FATTR4_WORD1_SPACE_FREE | + (attrmask[1 ] & (FATTR4_WORD1_SPACE_AVAIL |FATTR4_WORD1_SPACE_FREE |FATTR4_WORD1_SPACE_TOTAL ))) { err =vfs_statfs (&path, &args.statfs);if (err) goto out_nfserr; } -if ((u.attrmask[0 ] & (FATTR4_WORD0_FILEHANDLE |FATTR4_WORD0_FSID )) && +if ((attrmask[0 ] & (FATTR4_WORD0_FILEHANDLE |FATTR4_WORD0_FSID )) && !fhp) { tempfh =kmalloc (sizeof (struct svc_fh ),GFP_KERNEL ); status = nfserr_jukebox;
@@ -3571,10 +3568,10 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr, args.fhp = fhp; args.acl =NULL ; -if (u.attrmask[0 ] &FATTR4_WORD0_ACL ) { +if (attrmask[0 ] &FATTR4_WORD0_ACL ) { err =nfsd4_get_nfs4_acl (rqstp, dentry, &args.acl);if (err == -EOPNOTSUPP ) - u.attrmask[0 ] &= ~FATTR4_WORD0_ACL ; + attrmask[0 ] &= ~FATTR4_WORD0_ACL ;else if (err == -EINVAL ) { status = nfserr_attrnotsupp; goto out;
@@ -3586,17 +3583,17 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,#ifdef CONFIG_NFSD_V4_SECURITY_LABEL args.context =NULL ; -if ((u.attrmask[2 ] &FATTR4_WORD2_SECURITY_LABEL ) || - u.attrmask[0 ] &FATTR4_WORD0_SUPPORTED_ATTRS ) { +if ((attrmask[2 ] &FATTR4_WORD2_SECURITY_LABEL ) || + attrmask[0 ] &FATTR4_WORD0_SUPPORTED_ATTRS ) {if (exp->ex_flags &NFSEXP_SECURITY_LABEL ) err =security_inode_getsecctx (d_inode (dentry), &args.context, &args.contextlen);else err = -EOPNOTSUPP ; args.contextsupport = (err ==0 ); -if (u.attrmask[2 ] &FATTR4_WORD2_SECURITY_LABEL ) { +if (attrmask[2 ] &FATTR4_WORD2_SECURITY_LABEL ) {if (err == -EOPNOTSUPP ) - u.attrmask[2 ] &= ~FATTR4_WORD2_SECURITY_LABEL ; + attrmask[2 ] &= ~FATTR4_WORD2_SECURITY_LABEL ;else if (err) goto out_nfserr; }
@@ -3604,8 +3601,8 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr,#endif /* CONFIG_NFSD_V4_SECURITY_LABEL */ /* attrmask */ - status =nfsd4_encode_bitmap4 (xdr, u.attrmask[0 ], - u.attrmask[1 ], u.attrmask[2 ]); + status =nfsd4_encode_bitmap4 (xdr, attrmask[0 ], attrmask[1 ], + attrmask[2 ]);if (status) goto out;
@@ -3614,7 +3611,9 @@ nfsd4_encode_fattr4(struct svc_rqst *rqstp, struct xdr_stream *xdr, attrlen_p =xdr_reserve_space (xdr,XDR_UNIT );if (!attrlen_p) goto out_resource; -for_each_set_bit (bit, (const unsigned long *)&u.mask, +bitmap_from_arr32 (attr_bitmap, attrmask, +ARRAY_SIZE (nfsd4_enc_fattr4_encode_ops)); +for_each_set_bit (bit, attr_bitmap,ARRAY_SIZE (nfsd4_enc_fattr4_encode_ops)) { status = nfsd4_enc_fattr4_encode_ops[bit](xdr, &args);if (status != nfs_ok)
Signature · 1 line
2.43.0
Re: [PATCH 6.8.y] NFSD: fix endianness issue in nfsd4_encode_fattr4
Quoted 11 lines · On Tue, Apr 23, 2024 at 12:37:02PM -0400, [email protected] wrote:
From: Vasily Gorbik <[email protected]>
[ Upstream commit
f488138b526715c6d2568d7329c4477911be4210]The nfs4 mount fails with EIO on 64-bit big endian architectures since v6.7. The issue arises from employing a union in the
nfsd4_encode_fattr4()function to overlay a 32-bit array with a 64-bit values based bitmap, which does not function as intended. Address the endianness issue by utilizingbitmap_from_arr32()to copy 32-bit attribute masks into a bitmap in an endianness-agnostic manner.
Quoted 6 lines
Fixes fce7913b13d0 ("NFSD: Use a bitmask loop to encode FATTR4 results")Signed-off-by Vasily Gorbik <[email protected]>Reviewed-by Jeff Layton <[email protected]>[ cel: adjusted to apply on 6.8.y ]
This is already in the queue for 6.8.y, perhaps you missed the email saying that.
Anyway, thanks for the patch, all should be good now.
greg k-h