svn commit: r359941 - in head/sys/fs: nfsclient nfsserver
Rick Macklem
rmacklem at FreeBSD.org
Tue Apr 14 22:57:22 UTC 2020
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 at amazon.com> (earlier version)
Reported by: Frank van der Linden <fllinder at 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);
More information about the svn-src-all
mailing list