Date: Tue, 14 Apr 2020 22:57:21 +0000 (UTC) From: Rick Macklem <rmacklem@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r359941 - in head/sys/fs: nfsclient nfsserver Message-ID: <202004142257.03EMvLup090397@repo.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: rmacklem Date: Tue Apr 14 22:57:21 2020 New Revision: 359941 URL: https://svnweb.freebsd.org/changeset/base/359941 Log: Fix the NFSv2 extended attribute support to handle 0 length attributes. I did not realize that zero length attributes are allowed, but they are. This patch fixes the NFSv4.2 client and server to handle zero length extended attributes correctly. Submitted by: Frank van der Linden <fllinden@amazon.com> (earlier version) Reported by: Frank van der Linden <fllinder@amazon.com> Modified: head/sys/fs/nfsclient/nfs_clrpcops.c head/sys/fs/nfsclient/nfs_clvnops.c head/sys/fs/nfsserver/nfs_nfsdport.c head/sys/fs/nfsserver/nfs_nfsdserv.c Modified: head/sys/fs/nfsclient/nfs_clrpcops.c ============================================================================== --- head/sys/fs/nfsclient/nfs_clrpcops.c Tue Apr 14 22:48:33 2020 (r359940) +++ head/sys/fs/nfsclient/nfs_clrpcops.c Tue Apr 14 22:57:21 2020 (r359941) @@ -8341,7 +8341,7 @@ nfsrpc_getextattr(vnode_t vp, const char *name, struct } else if (uiop == NULL && len > 0) { /* Just wants the length and not the data. */ error = nfsm_advance(nd, NFSM_RNDUP(len), -1); - } else + } else if (len > 0) error = ENOATTR; if (error != 0) goto nfsmout; Modified: head/sys/fs/nfsclient/nfs_clvnops.c ============================================================================== --- head/sys/fs/nfsclient/nfs_clvnops.c Tue Apr 14 22:48:33 2020 (r359940) +++ head/sys/fs/nfsclient/nfs_clvnops.c Tue Apr 14 22:57:21 2020 (r359941) @@ -3982,7 +3982,7 @@ nfs_setextattr(struct vop_setextattr_args *ap) } mtx_unlock(&nmp->nm_mtx); - if (ap->a_uio->uio_resid <= 0) + if (ap->a_uio->uio_resid < 0) return (EINVAL); cred = ap->a_cred; if (cred == NULL) Modified: head/sys/fs/nfsserver/nfs_nfsdport.c ============================================================================== --- head/sys/fs/nfsserver/nfs_nfsdport.c Tue Apr 14 22:48:33 2020 (r359940) +++ head/sys/fs/nfsserver/nfs_nfsdport.c Tue Apr 14 22:57:21 2020 (r359941) @@ -6159,8 +6159,14 @@ nfsvno_getxattr(struct vnode *vp, char *name, uint32_t return (NFSERR_XATTR2BIG); len = siz; tlen = NFSM_RNDUP(len); - uiop->uio_iovcnt = nfsrv_createiovec(tlen, &m, &m2, &iv); - uiop->uio_iov = iv; + if (tlen > 0) { + uiop->uio_iovcnt = nfsrv_createiovec(tlen, &m, &m2, &iv); + uiop->uio_iov = iv; + } else { + uiop->uio_iovcnt = 0; + uiop->uio_iov = iv = NULL; + m = m2 = NULL; + } uiop->uio_offset = 0; uiop->uio_resid = tlen; uiop->uio_rw = UIO_READ; @@ -6173,8 +6179,9 @@ nfsvno_getxattr(struct vnode *vp, char *name, uint32_t goto out; #endif - error = VOP_GETEXTATTR(vp, EXTATTR_NAMESPACE_USER, name, uiop, NULL, - cred, p); + if (tlen > 0) + error = VOP_GETEXTATTR(vp, EXTATTR_NAMESPACE_USER, name, uiop, + NULL, cred, p); if (error != 0) goto out; if (uiop->uio_resid > 0) { @@ -6191,7 +6198,8 @@ nfsvno_getxattr(struct vnode *vp, char *name, uint32_t out: if (error != 0) { - m_freem(m); + if (m != NULL) + m_freem(m); *lenp = 0; } free(iv, M_TEMP); @@ -6223,9 +6231,14 @@ nfsvno_setxattr(struct vnode *vp, char *name, int len, uiop->uio_td = p; uiop->uio_offset = 0; uiop->uio_resid = len; - error = nfsrv_createiovecw(len, m, cp, &iv, &cnt); - uiop->uio_iov = iv; - uiop->uio_iovcnt = cnt; + if (len > 0) { + error = nfsrv_createiovecw(len, m, cp, &iv, &cnt); + uiop->uio_iov = iv; + uiop->uio_iovcnt = cnt; + } else { + uiop->uio_iov = iv = NULL; + uiop->uio_iovcnt = 0; + } if (error == 0) { error = VOP_SETEXTATTR(vp, EXTATTR_NAMESPACE_USER, name, uiop, cred, p); Modified: head/sys/fs/nfsserver/nfs_nfsdserv.c ============================================================================== --- head/sys/fs/nfsserver/nfs_nfsdserv.c Tue Apr 14 22:48:33 2020 (r359940) +++ head/sys/fs/nfsserver/nfs_nfsdserv.c Tue Apr 14 22:57:21 2020 (r359941) @@ -5564,9 +5564,11 @@ nfsrvd_getxattr(struct nfsrv_descript *nd, __unused in if (nd->nd_repstat == 0) { NFSM_BUILD(tl, uint32_t *, NFSX_UNSIGNED); *tl = txdr_unsigned(len); - nd->nd_mb->m_next = mp; - nd->nd_mb = mpend; - nd->nd_bpos = mtod(mpend, caddr_t) + mpend->m_len; + if (len > 0) { + nd->nd_mb->m_next = mp; + nd->nd_mb = mpend; + nd->nd_bpos = mtod(mpend, caddr_t) + mpend->m_len; + } } free(name, M_TEMP); @@ -5616,7 +5618,7 @@ nfsrvd_setxattr(struct nfsrv_descript *nd, __unused in goto nfsmout; NFSM_DISSECT(tl, uint32_t *, NFSX_UNSIGNED); len = fxdr_unsigned(int, *tl); - if (len <= 0 || len > IOSIZE_MAX) { + if (len < 0 || len > IOSIZE_MAX) { nd->nd_repstat = NFSERR_XATTR2BIG; goto nfsmout; } @@ -5652,7 +5654,7 @@ nfsrvd_setxattr(struct nfsrv_descript *nd, __unused in if (nd->nd_repstat == ENXIO) nd->nd_repstat = NFSERR_XATTR2BIG; } - if (nd->nd_repstat == 0) + if (nd->nd_repstat == 0 && len > 0) nd->nd_repstat = nfsm_advance(nd, NFSM_RNDUP(len), -1); if (nd->nd_repstat == 0) nd->nd_repstat = nfsvno_getattr(vp, &nva, nd, p, 1, &attrbits);
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202004142257.03EMvLup090397>